From c99b90edb85ea0a5be6ce567a8c0147b76534e15 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 13 Aug 2013 22:26:42 +0000 Subject: [PATCH] sizeof(void) etc. should be a hard error in C++. PR16872. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188324 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 3 +++ lib/Sema/SemaExpr.cpp | 16 ++++++++++++++++ test/CXX/expr/expr.post/expr.call/p7-0x.cpp | 2 +- test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp | 2 +- test/CXX/expr/expr.unary/expr.sizeof/p1.cpp | 8 ++++++++ test/SemaCXX/alignof-sizeof-reference.cpp | 4 ++-- test/SemaCXX/attr-cxx0x.cpp | 2 +- test/SemaCXX/dcl_ambig_res.cpp | 4 +--- test/SemaTemplate/constexpr-instantiate.cpp | 4 ++-- test/SemaTemplate/resolve-single-template-id.cpp | 2 +- 10 files changed, 36 insertions(+), 11 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 72a6fd9654..06053501fa 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 268a2fd343..2edddbbc23 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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; diff --git a/test/CXX/expr/expr.post/expr.call/p7-0x.cpp b/test/CXX/expr/expr.post/expr.call/p7-0x.cpp index c77c47df24..fbb685c5a4 100644 --- a/test/CXX/expr/expr.post/expr.call/p7-0x.cpp +++ b/test/CXX/expr/expr.post/expr.call/p7-0x.cpp @@ -38,7 +38,7 @@ namespace PR11131 { S &getS(); - void f(...); + int f(...); void g() { (void)sizeof(f(getS())); diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp index c6ed308d79..1fbe28722a 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp @@ -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}} } diff --git a/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp index 6a59e3d7ae..77d786568b 100644 --- a/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp +++ b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp @@ -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}} +} diff --git a/test/SemaCXX/alignof-sizeof-reference.cpp b/test/SemaCXX/alignof-sizeof-reference.cpp index d76fcf55c2..3e37d615bb 100644 --- a/test/SemaCXX/alignof-sizeof-reference.cpp +++ b/test/SemaCXX/alignof-sizeof-reference.cpp @@ -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}} diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp index fb46af4035..e24e12e50c 100644 --- a/test/SemaCXX/attr-cxx0x.cpp +++ b/test/SemaCXX/attr-cxx0x.cpp @@ -44,4 +44,4 @@ static_assert(alignof(align_class_temp_pack_type) == alignof(l static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's alignment is wrong"); static_assert(alignof(outer::inner) == 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}} diff --git a/test/SemaCXX/dcl_ambig_res.cpp b/test/SemaCXX/dcl_ambig_res.cpp index 97780e41f0..c0f1e2e96a 100644 --- a/test/SemaCXX/dcl_ambig_res.cpp +++ b/test/SemaCXX/dcl_ambig_res.cpp @@ -44,9 +44,7 @@ S4 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: diff --git a/test/SemaTemplate/constexpr-instantiate.cpp b/test/SemaTemplate/constexpr-instantiate.cpp index 80c4aaf856..95d6c23b9e 100644 --- a/test/SemaTemplate/constexpr-instantiate.cpp +++ b/test/SemaTemplate/constexpr-instantiate.cpp @@ -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)); } diff --git a/test/SemaTemplate/resolve-single-template-id.cpp b/test/SemaTemplate/resolve-single-template-id.cpp index c436225b24..7fb16eb467 100644 --- a/test/SemaTemplate/resolve-single-template-id.cpp +++ b/test/SemaTemplate/resolve-single-template-id.cpp @@ -33,7 +33,7 @@ int main() oneT; // expected-warning {{expression result unused}} twoT; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} typeid(oneT); // expected-warning{{expression result unused}} - sizeof(oneT); // expected-warning {{expression result unused}} + sizeof(oneT); // expected-error {{invalid application of 'sizeof' to a function type}} sizeof(twoT); //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} decltype(oneT)* fun = 0; -- 2.40.0