]> granicus.if.org Git - clang/commitdiff
Also promote fp16 types to double when they're anonymous variadic arguments.
authorTim Northover <Tim.Northover@arm.com>
Wed, 30 Jan 2013 09:46:55 +0000 (09:46 +0000)
committerTim Northover <Tim.Northover@arm.com>
Wed, 30 Jan 2013 09:46:55 +0000 (09:46 +0000)
__fp16 isn't covered by the standard, but this resolves the oddity that float
gets promoted when passed variadically, but not the smaller type. This is
required by the AArch64 ABI, and a sane action elsewhere.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173918 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/Sema/variadic-promotion.c [new file with mode: 0644]

index fd165aca89ef048046dda650fe17e1186ab707b7..5998fc9a028b8b01ccf0b6e7da8692cd76d8a972 100644 (file)
@@ -581,8 +581,9 @@ ExprResult Sema::UsualUnaryConversions(Expr *E) {
 }
 
 /// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
-/// do not have a prototype. Arguments that have type float are promoted to
-/// double. All other argument types are converted by UsualUnaryConversions().
+/// do not have a prototype. Arguments that have type float or __fp16
+/// are promoted to double. All other argument types are converted by
+/// UsualUnaryConversions().
 ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
   QualType Ty = E->getType();
   assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type");
@@ -592,8 +593,11 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
     return Owned(E);
   E = Res.take();
 
-  // If this is a 'float' (CVR qualified or typedef) promote to double.
-  if (Ty->isSpecificBuiltinType(BuiltinType::Float))
+  // If this is a 'float' or '__fp16' (CVR qualified or typedef) promote to
+  // double.
+  const BuiltinType *BTy = Ty->getAs<BuiltinType>();
+  if (BTy && (BTy->getKind() == BuiltinType::Half ||
+              BTy->getKind() == BuiltinType::Float))
     E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).take();
 
   // C++ performs lvalue-to-rvalue conversion as a default argument
diff --git a/test/Sema/variadic-promotion.c b/test/Sema/variadic-promotion.c
new file mode 100644 (file)
index 0000000..b248774
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -ast-dump %s | FileCheck %s
+
+void variadic(int, ...);
+
+void test_floating_promotion(__fp16 *f16, float f32, double f64) {
+  variadic(3, *f16, f32, f64);
+
+// CHECK: ImplicitCastExpr {{.*}} 'double' <FloatingCast>
+// CHECK-NEXT: 'half'
+
+// CHECK: ImplicitCastExpr {{.*}} 'double' <FloatingCast>
+// CHECK-NEXT: 'float'
+}