170e7aa4aSSerge Pavlov // Test without serialization:
270e7aa4aSSerge Pavlov // RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux -std=c++11 -ast-dump %s \
370e7aa4aSSerge Pavlov // RUN: | FileCheck --strict-whitespace %s
470e7aa4aSSerge Pavlov
570e7aa4aSSerge Pavlov // Test with serialization:
670e7aa4aSSerge Pavlov // RUN: %clang_cc1 -triple x86_64-pc-linux -emit-pch -o %t %s
770e7aa4aSSerge Pavlov // RUN: %clang_cc1 -x c++ -triple x86_64-pc-linux -include-pch %t -ast-dump-all /dev/null \
870e7aa4aSSerge Pavlov // RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
970e7aa4aSSerge Pavlov // RUN: | FileCheck --strict-whitespace %s
1070e7aa4aSSerge Pavlov
1170e7aa4aSSerge Pavlov float func_01(float x);
1270e7aa4aSSerge Pavlov
1370e7aa4aSSerge Pavlov template <typename T>
func_02(T x)1470e7aa4aSSerge Pavlov T func_02(T x) {
1570e7aa4aSSerge Pavlov #pragma STDC FP_CONTRACT ON
1670e7aa4aSSerge Pavlov return func_01(x);
1770e7aa4aSSerge Pavlov }
1870e7aa4aSSerge Pavlov
func_03(float x)1970e7aa4aSSerge Pavlov float func_03(float x) {
2070e7aa4aSSerge Pavlov #pragma STDC FP_CONTRACT OFF
2170e7aa4aSSerge Pavlov return func_02(x);
2270e7aa4aSSerge Pavlov }
2370e7aa4aSSerge Pavlov
2470e7aa4aSSerge Pavlov // CHECK: FunctionTemplateDecl {{.*}} func_02
2570e7aa4aSSerge Pavlov // CHECK: FunctionDecl {{.*}} func_02 'float (float)'
2670e7aa4aSSerge Pavlov // CHECK-NEXT: TemplateArgument type 'float'
2770e7aa4aSSerge Pavlov // CHECK-NEXT: BuiltinType {{.*}} 'float'
2870e7aa4aSSerge Pavlov // CHECK-NEXT: ParmVarDecl {{.*}} x 'float'
2970e7aa4aSSerge Pavlov // CHECK-NEXT: CompoundStmt
3070e7aa4aSSerge Pavlov // CHECK-NEXT: ReturnStmt
3170e7aa4aSSerge Pavlov // CHECK-NEXT: CallExpr {{.*}} FPContractMode=1
3270e7aa4aSSerge Pavlov
3370e7aa4aSSerge Pavlov // CHECK: FunctionDecl {{.*}} func_03 'float (float)'
3470e7aa4aSSerge Pavlov // CHECK-NEXT: ParmVarDecl {{.*}} x 'float'
3570e7aa4aSSerge Pavlov // CHECK-NEXT: CompoundStmt
3670e7aa4aSSerge Pavlov // CHECK-NEXT: ReturnStmt
3770e7aa4aSSerge Pavlov // CHECK-NEXT: CallExpr {{.*}} FPContractMode=0
38a633da53SSerge Pavlov
func_04(float x)39f1cd6593SSerge Pavlov int func_04(float x) {
40f1cd6593SSerge Pavlov #pragma STDC FP_CONTRACT ON
41f1cd6593SSerge Pavlov return x;
42f1cd6593SSerge Pavlov }
43a633da53SSerge Pavlov
44f1cd6593SSerge Pavlov // CHECK: FunctionDecl {{.*}} func_04 'int (float)'
45f1cd6593SSerge Pavlov // CHECK-NEXT: ParmVarDecl {{.*}} x 'float'
46f1cd6593SSerge Pavlov // CHECK-NEXT: CompoundStmt
47f1cd6593SSerge Pavlov // CHECK-NEXT: ReturnStmt
48f1cd6593SSerge Pavlov // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <FloatingToIntegral> FPContractMode=1
49a633da53SSerge Pavlov
func_05(double x)50f1cd6593SSerge Pavlov float func_05(double x) {
51f1cd6593SSerge Pavlov #pragma STDC FP_CONTRACT ON
52f1cd6593SSerge Pavlov return (float)x;
53f1cd6593SSerge Pavlov }
54f1cd6593SSerge Pavlov
55f1cd6593SSerge Pavlov // CHECK: FunctionDecl {{.*}} func_05 'float (double)'
56f1cd6593SSerge Pavlov // CHECK-NEXT: ParmVarDecl {{.*}} x 'double'
57f1cd6593SSerge Pavlov // CHECK-NEXT: CompoundStmt
58f1cd6593SSerge Pavlov // CHECK-NEXT: ReturnStmt
59f1cd6593SSerge Pavlov // CHECK-NEXT: CStyleCastExpr {{.*}} FPContractMode=1
60f1cd6593SSerge Pavlov
func_06(double x)61f1cd6593SSerge Pavlov float func_06(double x) {
62f1cd6593SSerge Pavlov #pragma STDC FP_CONTRACT ON
63f1cd6593SSerge Pavlov return float(x);
64f1cd6593SSerge Pavlov }
65f1cd6593SSerge Pavlov
66f1cd6593SSerge Pavlov // CHECK: FunctionDecl {{.*}} func_06 'float (double)'
67f1cd6593SSerge Pavlov // CHECK-NEXT: ParmVarDecl {{.*}} x 'double'
68f1cd6593SSerge Pavlov // CHECK-NEXT: CompoundStmt
69f1cd6593SSerge Pavlov // CHECK-NEXT: ReturnStmt
70f1cd6593SSerge Pavlov // CHECK-NEXT: CXXFunctionalCastExpr {{.*}} FPContractMode=1
71f1cd6593SSerge Pavlov
func_07(double x)72f1cd6593SSerge Pavlov float func_07(double x) {
73f1cd6593SSerge Pavlov #pragma STDC FP_CONTRACT ON
74f1cd6593SSerge Pavlov return static_cast<float>(x);
75f1cd6593SSerge Pavlov }
76f1cd6593SSerge Pavlov
77f1cd6593SSerge Pavlov // CHECK: FunctionDecl {{.*}} func_07 'float (double)'
78f1cd6593SSerge Pavlov // CHECK-NEXT: ParmVarDecl {{.*}} x 'double'
79f1cd6593SSerge Pavlov // CHECK-NEXT: CompoundStmt
80f1cd6593SSerge Pavlov // CHECK-NEXT: ReturnStmt
81f1cd6593SSerge Pavlov // CHECK-NEXT: CXXStaticCastExpr {{.*}} FPContractMode=1
82a633da53SSerge Pavlov
83a633da53SSerge Pavlov #pragma STDC FENV_ROUND FE_DOWNWARD
84a633da53SSerge Pavlov
func_10(float x,float y)85a633da53SSerge Pavlov float func_10(float x, float y) {
86a633da53SSerge Pavlov return x + y;
87a633da53SSerge Pavlov }
88a633da53SSerge Pavlov
89a633da53SSerge Pavlov // CHECK-LABEL: FunctionDecl {{.*}} func_10 'float (float, float)'
90706e89dbSSerge Pavlov // CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward
91a633da53SSerge Pavlov
func_11(float x,float y)92a633da53SSerge Pavlov float func_11(float x, float y) {
93a633da53SSerge Pavlov if (x < 0) {
94a633da53SSerge Pavlov #pragma STDC FENV_ROUND FE_UPWARD
95a633da53SSerge Pavlov return x + y;
96a633da53SSerge Pavlov }
97a633da53SSerge Pavlov return x - y;
98a633da53SSerge Pavlov }
99a633da53SSerge Pavlov
100a633da53SSerge Pavlov // CHECK-LABEL: FunctionDecl {{.*}} func_11 'float (float, float)'
101706e89dbSSerge Pavlov // CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=upward
102706e89dbSSerge Pavlov // CHECK: BinaryOperator {{.*}} 'float' '-' ConstRoundingMode=downward
103a633da53SSerge Pavlov
104a633da53SSerge Pavlov
105a633da53SSerge Pavlov #pragma STDC FENV_ROUND FE_DYNAMIC
106a633da53SSerge Pavlov
func_12(float x,float y)107a633da53SSerge Pavlov float func_12(float x, float y) {
108a633da53SSerge Pavlov return x + y;
109a633da53SSerge Pavlov }
110a633da53SSerge Pavlov
111a633da53SSerge Pavlov // CHECK-LABEL: FunctionDecl {{.*}} func_12 'float (float, float)'
112706e89dbSSerge Pavlov // CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=dynamic
113a633da53SSerge Pavlov
114a633da53SSerge Pavlov #pragma STDC FENV_ROUND FE_TONEAREST
115a633da53SSerge Pavlov
func_13(float x,float y)116a633da53SSerge Pavlov float func_13(float x, float y) {
117a633da53SSerge Pavlov return x + y;
118a633da53SSerge Pavlov }
119a633da53SSerge Pavlov
120a633da53SSerge Pavlov // CHECK-LABEL: FunctionDecl {{.*}} func_13 'float (float, float)'
121706e89dbSSerge Pavlov // CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=tonearest
122a633da53SSerge Pavlov
123a633da53SSerge Pavlov
124a633da53SSerge Pavlov template <typename T>
func_14(T x,T y)125a633da53SSerge Pavlov T func_14(T x, T y) {
126a633da53SSerge Pavlov #pragma STDC FENV_ROUND FE_TOWARDZERO
127a633da53SSerge Pavlov return x + y;
128a633da53SSerge Pavlov }
129a633da53SSerge Pavlov
func_15(float x,float y)130a633da53SSerge Pavlov float func_15(float x, float y) {
131f1cd6593SSerge Pavlov #pragma STDC FENV_ROUND FE_DOWNWARD
132a633da53SSerge Pavlov return func_14(x, y);
133a633da53SSerge Pavlov }
134a633da53SSerge Pavlov
135a633da53SSerge Pavlov // CHECK-LABEL: FunctionTemplateDecl {{.*}} func_14
136a633da53SSerge Pavlov // CHECK: FunctionDecl {{.*}} func_14 'T (T, T)'
137a633da53SSerge Pavlov // CHECK: CompoundStmt
138a633da53SSerge Pavlov // CHECK-NEXT: ReturnStmt
139706e89dbSSerge Pavlov // CHECK-NEXT: BinaryOperator {{.*}} '+' ConstRoundingMode=towardzero
140a633da53SSerge Pavlov // CHECK: FunctionDecl {{.*}} func_14 'float (float, float)'
141a633da53SSerge Pavlov // CHECK: CompoundStmt
142a633da53SSerge Pavlov // CHECK-NEXT: ReturnStmt
143706e89dbSSerge Pavlov // CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=towardzero
144*f7819ce1SSerge Pavlov
func_16(float x,float y)145*f7819ce1SSerge Pavlov float func_16(float x, float y) {
146*f7819ce1SSerge Pavlov #pragma STDC FENV_ROUND FE_TOWARDZERO
147*f7819ce1SSerge Pavlov if (x < 0) {
148*f7819ce1SSerge Pavlov #pragma STDC FENV_ROUND FE_UPWARD
149*f7819ce1SSerge Pavlov return x - y;
150*f7819ce1SSerge Pavlov }
151*f7819ce1SSerge Pavlov return x + y;
152*f7819ce1SSerge Pavlov }
153*f7819ce1SSerge Pavlov
154*f7819ce1SSerge Pavlov // CHECK-LABEL: FunctionDecl {{.*}} func_16 'float (float, float)'
155*f7819ce1SSerge Pavlov // CHECK: CompoundStmt {{.*}} ConstRoundingMode=towardzero
156*f7819ce1SSerge Pavlov // CHECK: IfStmt
157*f7819ce1SSerge Pavlov // CHECK: CompoundStmt {{.*}} ConstRoundingMode=upward
158*f7819ce1SSerge Pavlov // CHECK: ReturnStmt
159*f7819ce1SSerge Pavlov // CHECK: BinaryOperator {{.*}} ConstRoundingMode=upward
160*f7819ce1SSerge Pavlov // CHECK: ReturnStmt
161*f7819ce1SSerge Pavlov // CHECK: BinaryOperator {{.*}} ConstRoundingMode=towardzero
162*f7819ce1SSerge Pavlov
func_17(float x,float y)163*f7819ce1SSerge Pavlov float func_17(float x, float y) {
164*f7819ce1SSerge Pavlov #pragma STDC FENV_ROUND FE_TOWARDZERO
165*f7819ce1SSerge Pavlov if (x < 0) {
166*f7819ce1SSerge Pavlov #pragma STDC FENV_ROUND FE_TOWARDZERO
167*f7819ce1SSerge Pavlov return x - y;
168*f7819ce1SSerge Pavlov }
169*f7819ce1SSerge Pavlov return x + y;
170*f7819ce1SSerge Pavlov }
171*f7819ce1SSerge Pavlov
172*f7819ce1SSerge Pavlov // CHECK-LABEL: FunctionDecl {{.*}} func_17 'float (float, float)'
173*f7819ce1SSerge Pavlov // CHECK: CompoundStmt {{.*}} ConstRoundingMode=towardzero
174*f7819ce1SSerge Pavlov // CHECK: IfStmt
175*f7819ce1SSerge Pavlov // CHECK: CompoundStmt {{.*}}
176*f7819ce1SSerge Pavlov // CHECK: ReturnStmt
177*f7819ce1SSerge Pavlov // CHECK: BinaryOperator {{.*}} ConstRoundingMode=towardzero
178*f7819ce1SSerge Pavlov // CHECK: ReturnStmt
179*f7819ce1SSerge Pavlov // CHECK: BinaryOperator {{.*}} ConstRoundingMode=towardzero
180*f7819ce1SSerge Pavlov
181*f7819ce1SSerge Pavlov #pragma STDC FENV_ROUND FE_DOWNWARD
func_18(float x,float y)182*f7819ce1SSerge Pavlov float func_18(float x, float y) {
183*f7819ce1SSerge Pavlov return x + y;
184*f7819ce1SSerge Pavlov }
185*f7819ce1SSerge Pavlov
186*f7819ce1SSerge Pavlov // CHECK-LABEL: FunctionDecl {{.*}} func_18 'float (float, float)'
187*f7819ce1SSerge Pavlov // CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward
188*f7819ce1SSerge Pavlov // CHECK: ReturnStmt
189*f7819ce1SSerge Pavlov // CHECK: BinaryOperator {{.*}} ConstRoundingMode=downward
190