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