From a0109e284457c996d4eb8f231e01dda303d1a345 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 29 Jan 2013 10:18:18 +0000 Subject: [PATCH] Produce a diagnostic if alignas is applied to an expression. Neither C11 nor C++11 allows that. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173789 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticParseKinds.td | 2 ++ lib/Parse/ParseExpr.cpp | 9 ++++++--- test/SemaCXX/alignof-sizeof-reference.cpp | 6 ++++-- test/SemaCXX/attr-cxx0x.cpp | 6 +++--- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 474428efa3..a3ad84edf3 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -95,6 +95,8 @@ def warn_cxx98_compat_enum_fixed_underlying_type : Warning< def warn_cxx98_compat_alignof : Warning< "alignof expressions are incompatible with C++98">, InGroup, DefaultIgnore; +def ext_alignof_expr : ExtWarn< + "%0 applied to an expression is a GNU extension">, InGroup; def warn_microsoft_dependent_exists : Warning< "dependent %select{__if_not_exists|__if_exists}0 declarations are ignored">, diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 9c788a1336..86cf657674 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1609,11 +1609,11 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, /// unary-expression: [C99 6.5.3] /// 'sizeof' unary-expression /// 'sizeof' '(' type-name ')' -/// [C++0x] 'sizeof' '...' '(' identifier ')' +/// [C++11] 'sizeof' '...' '(' identifier ')' /// [GNU] '__alignof' unary-expression /// [GNU] '__alignof' '(' type-name ')' /// [C11] '_Alignof' '(' type-name ')' -/// [C++0x] 'alignof' '(' type-id ')' +/// [C++11] 'alignof' '(' type-id ')' /// \endverbatim ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof) || @@ -1623,7 +1623,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { Token OpTok = Tok; ConsumeToken(); - // [C++0x] 'sizeof' '...' '(' identifier ')' + // [C++11] 'sizeof' '...' '(' identifier ')' if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) { SourceLocation EllipsisLoc = ConsumeToken(); SourceLocation LParenLoc, RParenLoc; @@ -1694,6 +1694,9 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { CastTy.getAsOpaquePtr(), CastRange); + if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof)) + Diag(OpTok, diag::ext_alignof_expr) << OpTok.getIdentifierInfo(); + // If we get here, the operand to the sizeof/alignof was an expresion. if (!Operand.isInvalid()) Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), diff --git a/test/SemaCXX/alignof-sizeof-reference.cpp b/test/SemaCXX/alignof-sizeof-reference.cpp index ccdf45e52d..d76fcf55c2 100644 --- a/test/SemaCXX/alignof-sizeof-reference.cpp +++ b/test/SemaCXX/alignof-sizeof-reference.cpp @@ -4,8 +4,10 @@ struct s0; // expected-note {{forward declaration}} char ar[sizeof(s0&)]; // expected-error {{invalid application of 'sizeof' to an incomplete type}} void test() { char &r = ar[0]; - static_assert(alignof(r) == 1, "bad alignment"); + static_assert(alignof(r) == 1, "bad alignment"); // expected-warning {{GNU extension}} + static_assert(alignof(char&) == 1, "bad alignment"); static_assert(sizeof(r) == 1, "bad size"); + static_assert(sizeof(char&) == 1, "bad size"); } void f(); // expected-note{{possible target for call}} @@ -18,5 +20,5 @@ void g() { template void f_template(); // expected-note{{possible target for call}} template void f_template(T*); // expected-note{{possible target for call}} void rdar9659191() { - (void)alignof(f_template); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}} + (void)alignof(f_template); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}} expected-warning {{GNU extension}} } diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp index c2576e9b0e..d038e637f4 100644 --- a/test/SemaCXX/attr-cxx0x.cpp +++ b/test/SemaCXX/attr-cxx0x.cpp @@ -28,9 +28,9 @@ template alignas(A...) struct align_class_temp_pack_expr {}; // typedef char align_typedef alignas(8); // expected-error {{'alignas' attribute only applies to variables, functions and tag types}} template using align_alias_template = align_typedef alignas(8); // expected-error {{'alignas' attribute cannot be applied to types}} -static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong"); -static_assert(alignof(align_small) == 1, "j's alignment is wrong"); -static_assert(alignof(align_multiple) == 8, "l's alignment is wrong"); +static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}} +static_assert(alignof(align_small) == 1, "j's alignment is wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}} +static_assert(alignof(align_multiple) == 8, "l's alignment is wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}} static_assert(alignof(align_member) == 8, "quuux's alignment is wrong"); static_assert(sizeof(align_member) == 8, "quuux's size is wrong"); static_assert(alignof(align_class_template<8>) == 8, "template's alignment is wrong"); -- 2.40.0