]> granicus.if.org Git - clang/commitdiff
sizeof(void) etc. should be a hard error in C++.
authorEli Friedman <eli.friedman@gmail.com>
Tue, 13 Aug 2013 22:26:42 +0000 (22:26 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Tue, 13 Aug 2013 22:26:42 +0000 (22:26 +0000)
PR16872.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/CXX/expr/expr.post/expr.call/p7-0x.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp
test/CXX/expr/expr.unary/expr.sizeof/p1.cpp
test/SemaCXX/alignof-sizeof-reference.cpp
test/SemaCXX/attr-cxx0x.cpp
test/SemaCXX/dcl_ambig_res.cpp
test/SemaTemplate/constexpr-instantiate.cpp
test/SemaTemplate/resolve-single-template-id.cpp

index 72a6fd9654dd51d8c6cd10479391a2ac354769e3..06053501fa636e27f4ecfb203e6632a68ba437e8 100644 (file)
@@ -4153,6 +4153,9 @@ def ext_sizeof_alignof_void_type : Extension<
 def err_sizeof_alignof_incomplete_type : Error<
   "invalid application of '%select{sizeof|alignof|vec_step}0' to an "
   "incomplete type %1">;
+def err_sizeof_alignof_function_type : Error<
+  "invalid application of '%select{sizeof|alignof|vec_step}0' to a "
+  "function type">;
 def err_sizeof_alignof_bitfield : Error<
   "invalid application of '%select{sizeof|alignof}0' to bit-field">;
 def err_alignof_member_of_incomplete_type : Error<
index 268a2fd343d24845eafd077c9a19818b76b2f8e6..2edddbbc23d60b4f7b292ecdaeed445d6d9a1087 100644 (file)
@@ -3176,6 +3176,10 @@ static bool CheckExtensionTraitOperandType(Sema &S, QualType T,
                                            SourceLocation Loc,
                                            SourceRange ArgRange,
                                            UnaryExprOrTypeTrait TraitKind) {
+  // Invalid types must be hard errors for SFINAE in C++.
+  if (S.LangOpts.CPlusPlus)
+    return true;
+
   // C99 6.5.3.4p1:
   if (T->isFunctionType() &&
       (TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf)) {
@@ -3258,6 +3262,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
   ExprTy = E->getType();
   assert(!ExprTy->isReferenceType());
 
+  if (ExprTy->isFunctionType()) {
+    Diag(E->getExprLoc(), diag::err_sizeof_alignof_function_type)
+      << ExprKind << E->getSourceRange();
+    return true;
+  }
+
   if (CheckObjCTraitOperandConstraints(*this, ExprTy, E->getExprLoc(),
                                        E->getSourceRange(), ExprKind))
     return true;
@@ -3331,6 +3341,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType,
                           ExprKind, ExprRange))
     return true;
 
+  if (ExprType->isFunctionType()) {
+    Diag(OpLoc, diag::err_sizeof_alignof_function_type)
+      << ExprKind << ExprRange;
+    return true;
+  }
+
   if (CheckObjCTraitOperandConstraints(*this, ExprType, OpLoc, ExprRange,
                                        ExprKind))
     return true;
index c77c47df244d7a34e10ad6155e00e607b564e759..fbb685c5a44889837c2cc457fff0ba3de9396ad0 100644 (file)
@@ -38,7 +38,7 @@ namespace PR11131 {
 
   S &getS();
 
-  void f(...);
+  int f(...);
 
   void g() {
     (void)sizeof(f(getS()));
index c6ed308d79a10d03bd3a2c7a787d4219295db83b..1fbe28722a41dcbce5c6c3db6bafce20ce48add8 100644 (file)
@@ -15,7 +15,7 @@ struct P {
 };
 
 void unevaluated_operand(P &p, int i) {
-  int i2 = sizeof([]()->void{}()); // expected-error{{lambda expression in an unevaluated operand}}
+  int i2 = sizeof([] ()->int { return 0; }()); // expected-error{{lambda expression in an unevaluated operand}}
   const std::type_info &ti1 = typeid([&]() -> P& { return p; }());
   const std::type_info &ti2 = typeid([&]() -> int { return i; }());  // expected-error{{lambda expression in an unevaluated operand}}
 }
index 6a59e3d7ae52617a8787acefe5975ced8d87f400..77d786568bdfd90e36ece89c0438af7e1c731e53 100644 (file)
@@ -18,3 +18,11 @@ void test(A *a) {
   x = sizeof(a->bitX = 3); // expected-error {{invalid application of 'sizeof' to bit-field}}
   x = sizeof(a->bitY += 3); // expected-error {{invalid application of 'sizeof' to bit-field}}
 }
+
+void test2() {
+  int x;
+  x = sizeof(void); // expected-error {{invalid application of 'sizeof' to an incomplete type 'void'}}
+  x = sizeof(int()); // expected-error {{invalid application of 'sizeof' to a function type}}
+  x = sizeof(test2()); // expected-error {{invalid application of 'sizeof' to an incomplete type 'void'}}
+  x = sizeof(test2); // expected-error {{invalid application of 'sizeof' to a function type}}
+}
index d76fcf55c2d85420582b635f42073dc6b2d68bf9..3e37d615bbcf55846ae2fbdad64866ab852e6fa3 100644 (file)
@@ -10,8 +10,8 @@ void test() {
   static_assert(sizeof(char&) == 1, "bad size");
 }
 
-void f();  // expected-note{{possible target for call}}
-void f(int);  // expected-note{{possible target for call}}
+int f();  // expected-note{{possible target for call}}
+int f(int);  // expected-note{{possible target for call}}
 void g() { 
   sizeof(&f); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} \
   // expected-warning{{expression result unused}}
index fb46af40359bd0200107a2af7b355db69d3d9d03..e24e12e50c4e4b974b4d6f0be34910da4d4f45be 100644 (file)
@@ -44,4 +44,4 @@ static_assert(alignof(align_class_temp_pack_type<short, int, long>) == alignof(l
 static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's alignment is wrong");
 static_assert(alignof(outer<int,char>::inner<double,short>) == alignof(int) * alignof(double), "template's alignment is wrong");
 
-static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-warning{{invalid application of 'alignof' to a function type}}
+static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-error{{invalid application of 'alignof' to a function type}}
index 97780e41f0c49cb2cb50b65c6cea5381557bf4c8..c0f1e2e96a4d59854c0fd22fa4a8886b21382373 100644 (file)
@@ -44,9 +44,7 @@ S4<int(1)> y; // expected-error{{must be a type}}
 void foo5() 
 { 
   (void)sizeof(int(1)); //expression 
-  // FIXME: should we make this an error rather than a warning? 
-  // (It affects SFINAE)
-  (void)sizeof(int()); // expected-warning{{function type}}
+  (void)sizeof(int()); // expected-error{{function type}}
 }
 
 // [dcl.ambig.res]p6:
index 80c4aaf85601870a39d4635a6cc7f20a4cb444dd..95d6c23b9e98855b39e28a8b9bfc5054f74ae137 100644 (file)
@@ -201,8 +201,8 @@ namespace NoInstantiationWhenSelectingOverload {
     int n;
   };
 
-  void f(S);
-  void f(int);
+  int f(S);
+  int f(int);
 
   void g() { f(0); }
   void h() { (void)sizeof(f(0)); }
index c436225b24cf16cb22964571dcc40acf637218f1..7fb16eb467459c00aa5e9266f2a3ed5814bca6e3 100644 (file)
@@ -33,7 +33,7 @@ int main()
    oneT<int>;  // expected-warning {{expression result unused}}
    twoT<int>;  // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
    typeid(oneT<int>); // expected-warning{{expression result unused}}
-  sizeof(oneT<int>); // expected-warning {{expression result unused}}
+  sizeof(oneT<int>); // expected-error {{invalid application of 'sizeof' to a function type}}
   sizeof(twoT<int>); //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
   decltype(oneT<int>)* fun = 0;