From 39da55e8f548a11f7dadefa73ea73d809a5f1729 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Tue, 17 Jan 2023 22:31:56 -0800 Subject: [PATCH] Revert "Diagnose extensions in 'offsetof'" This reverts commit f1f0a0d8e8fdd2e534d9423b2e64c6b8aaa53aee. Causes crashes on $ echo 'typedef int a; void c() { __builtin_offsetof(struct {a b}, b); }' | bin/clang -cc1 -emit-llvm -o /dev/null - -x c --- clang/docs/LanguageExtensions.rst | 44 -------------- clang/docs/ReleaseNotes.rst | 9 +-- clang/include/clang/Basic/DiagnosticGroups.td | 7 +-- clang/include/clang/Basic/DiagnosticParseKinds.td | 5 -- clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 - clang/include/clang/Parse/Parser.h | 3 - clang/include/clang/Parse/RAIIObjectsForParser.h | 13 ---- clang/include/clang/Sema/Sema.h | 12 +--- clang/lib/Parse/ParseDecl.cpp | 2 +- clang/lib/Parse/ParseDeclCXX.cpp | 2 +- clang/lib/Parse/ParseExpr.cpp | 28 ++------- clang/lib/Sema/SemaDecl.cpp | 12 +--- clang/lib/Sema/SemaDeclCXX.cpp | 6 +- clang/lib/Sema/SemaTemplate.cpp | 13 ++-- clang/test/C/C2x/n2350.c | 74 ----------------------- clang/test/C/drs/dr4xx.c | 14 ++--- clang/test/CXX/drs/dr4xx.cpp | 6 +- clang/test/Parser/declarators.c | 4 ++ clang/test/SemaCXX/offsetof.cpp | 15 ----- 19 files changed, 39 insertions(+), 233 deletions(-) delete mode 100644 clang/test/C/C2x/n2350.c diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index dbec1cd..9b39dc2 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -2360,50 +2360,6 @@ evaluated, so any side effects of the expression will be discarded. Query for this feature with ``__has_builtin(__builtin_assume)``. -``__builtin_offsetof`` ----------------------- - -``__builtin_offsetof`` is used to implement the ``offsetof`` macro, which -calculates the offset (in bytes) to a given member of the given type. - -**Syntax**: - -.. code-block:: c++ - - __builtin_offsetof(type-name, member-designator) - -**Example of Use**: - -.. code-block:: c++ - - struct S { - char c; - int i; - struct T { - float f[2]; - } t; - }; - - const int offset_to_i = __builtin_offsetof(struct S, i); - const int ext1 = __builtin_offsetof(struct U { int i; }, i); // C extension - const int ext2 = __builtin_offsetof(struct S, t.f[1]); // C & C++ extension - -**Description**: - -This builtin is usable in an integer constant expression which returns a value -of type ``size_t``. The value returned is the offset in bytes to the subobject -designated by the member-designator from the beginning of an object of type -``type-name``. Clang extends the required standard functionality in a few ways: - -* In C language modes, the first argument may be the definition of a new type. - Any type declared this way is scoped to the nearest scope containing the call - to the builtin. -* The second argument may be a member-designator designated by a series of - member access expressions using the dot (``.``) operator or array subscript - expressions. - -Query for this feature with ``__has_builtin(__builtin_offsetof)``. - ``__builtin_call_with_static_chain`` ------------------------------------ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 288904b..b912f77 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -504,8 +504,7 @@ Non-comprehensive list of changes in this release - Clang can now generate a PCH when using ``-fdelayed-template-parsing`` for code with templates containing loop hint pragmas, OpenMP pragmas, and ``#pragma unused``. -- Now diagnoses use of a member access expression or array subscript expression - within ``__builtin_offsetof`` and ``offsetof`` as being a Clang extension. + New Compiler Flags ------------------ @@ -685,12 +684,6 @@ C2x Feature Support va_end(list); } -- Diagnose type definitions in the ``type`` argument of ``__builtin_offsetof`` - as a conforming C extension according to - `WG14 N2350 `_. - Also documents the builtin appropriately. Note, a type definition in C++ - continues to be rejected. - C++ Language Changes in Clang ----------------------------- - Implemented `DR692 `_, `DR1395 `_, diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index d754fdb..f71bb40 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -173,7 +173,6 @@ def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor", DeleteAbstractNonVirtualDtor]>; def AbstractFinalClass : DiagGroup<"abstract-final-class">; def FinalDtorNonFinalClass : DiagGroup<"final-dtor-non-final-class">; -def GNUOffsetofExtensions : DiagGroup<"gnu-offsetof-extensions">; def CXX11CompatDeprecatedWritableStr : DiagGroup<"c++11-compat-deprecated-writable-strings">; @@ -1140,9 +1139,9 @@ def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct, GNUFlexibleArrayUnionMember, GNUFoldingConstant, GNUImaginaryConstant, GNUIncludeNext, GNULabelsAsValue, GNULineMarker, GNUNullPointerArithmetic, - GNUOffsetofExtensions, GNUPointerArith, - RedeclaredClassMember, GNURedeclaredEnum, - GNUStatementExpression, GNUStaticFloatInit, + GNUPointerArith, RedeclaredClassMember, + GNURedeclaredEnum, GNUStatementExpression, + GNUStaticFloatInit, GNUStringLiteralOperatorTemplate, GNUUnionCast, GNUVariableSizedTypeNotAtEnd, ZeroLengthArray, GNUZeroLineDirective, diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 6bc35fa..79035b4 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1607,11 +1607,6 @@ def err_import_in_wrong_fragment : Error< def err_export_empty : Error<"export declaration cannot be empty">; } -def ext_offsetof_member_designator : Extension< - "using %select{a member access expression|an array subscript expression}0 " - "within '%select{__builtin_offsetof|offsetof}1' is a Clang extension">, - InGroup; - let CategoryName = "Generics Issue" in { def err_objc_expected_type_parameter : Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 02a6c2c..318bbd7 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1650,9 +1650,6 @@ def err_type_defined_in_condition : Error< "%0 cannot be defined in a condition">; def err_type_defined_in_enum : Error< "%0 cannot be defined in an enumeration">; -def ext_type_defined_in_offsetof : Extension< - "defining a type within '%select{__builtin_offsetof|offsetof}0' is a Clang " - "extension">, InGroup; def note_pure_virtual_function : Note< "unimplemented pure virtual method %0 in %1">; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 6f9581b..7a33532 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -62,7 +62,6 @@ class Parser : public CodeCompletionHandler { friend class ColonProtectionRAIIObject; friend class ParsingOpenMPDirectiveRAII; friend class InMessageExpressionRAIIObject; - friend class OffsetOfStateRAIIObject; friend class PoisonSEHIdentifiersRAIIObject; friend class ObjCDeclContextSwitch; friend class ParenBraceBracketBalancer; @@ -249,8 +248,6 @@ class Parser : public CodeCompletionHandler { /// function call. bool CalledSignatureHelp = false; - Sema::OffsetOfKind OffsetOfState = Sema::OffsetOfKind::OOK_Outside; - /// The "depth" of the template parameters currently being parsed. unsigned TemplateParameterDepth; diff --git a/clang/include/clang/Parse/RAIIObjectsForParser.h b/clang/include/clang/Parse/RAIIObjectsForParser.h index cb525c9..5ae609e 100644 --- a/clang/include/clang/Parse/RAIIObjectsForParser.h +++ b/clang/include/clang/Parse/RAIIObjectsForParser.h @@ -341,19 +341,6 @@ namespace clang { } }; - class OffsetOfStateRAIIObject { - Sema::OffsetOfKind &OffsetOfState; - Sema::OffsetOfKind OldValue; - - public: - OffsetOfStateRAIIObject(Parser &P, Sema::OffsetOfKind Value) - : OffsetOfState(P.OffsetOfState), OldValue(P.OffsetOfState) { - OffsetOfState = Value; - } - - ~OffsetOfStateRAIIObject() { OffsetOfState = OldValue; } - }; - /// RAII object that makes sure paren/bracket/brace count is correct /// after declaration/statement parsing, even when there's a parsing error. class ParenBraceBracketBalancer { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 35e3198..30c5ea6 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3304,16 +3304,6 @@ public: TUK_Friend // Friend declaration: 'friend struct foo;' }; - enum OffsetOfKind { - // Not parsing a type within __builtin_offsetof. - OOK_Outside, - // Parsing a type within __builtin_offsetof. - OOK_Builtin, - // Parsing a type within macro "offsetof", defined in __buitin_offsetof - // To improve our diagnostic message. - OOK_Macro, - }; - Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, const ParsedAttributesView &Attr, @@ -3322,7 +3312,7 @@ public: bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, - OffsetOfKind OOK, SkipBodyInfo *SkipBody = nullptr); + SkipBodyInfo *SkipBody = nullptr); Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, unsigned TagSpec, SourceLocation TagLoc, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 75937c0..56fe9c3 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4972,7 +4972,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, DSC == DeclSpecContext::DSC_type_specifier, DSC == DeclSpecContext::DSC_template_param || DSC == DeclSpecContext::DSC_template_type_arg, - OffsetOfState, &SkipBody); + &SkipBody); if (SkipBody.ShouldSkip) { assert(TUK == Sema::TUK_Definition && "can only skip a definition"); diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 227c1df..5d721f4 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -2074,7 +2074,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, DSC == DeclSpecContext::DSC_type_specifier, DSC == DeclSpecContext::DSC_template_param || DSC == DeclSpecContext::DSC_template_type_arg, - OffsetOfState, &SkipBody); + &SkipBody); // If ActOnTag said the type was dependent, try again with the // less common call. diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 392ed29..b1bf988 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2592,21 +2592,10 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { } case tok::kw___builtin_offsetof: { SourceLocation TypeLoc = Tok.getLocation(); - auto OOK = Sema::OffsetOfKind::OOK_Builtin; - if (Tok.getLocation().isMacroID()) { - StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics( - Tok.getLocation(), PP.getSourceManager(), getLangOpts()); - if (MacroName == "offsetof") - OOK = Sema::OffsetOfKind::OOK_Macro; - } - TypeResult Ty; - { - OffsetOfStateRAIIObject InOffsetof(*this, OOK); - Ty = ParseTypeName(); - if (Ty.isInvalid()) { - SkipUntil(tok::r_paren, StopAtSemi); - return ExprError(); - } + TypeResult Ty = ParseTypeName(); + if (Ty.isInvalid()) { + SkipUntil(tok::r_paren, StopAtSemi); + return ExprError(); } if (ExpectAndConsume(tok::comma)) { @@ -2629,12 +2618,6 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); - enum class Kind { MemberAccess, ArraySubscript }; - auto DiagExt = [&](SourceLocation Loc, Kind K) { - Diag(Loc, diag::ext_offsetof_member_designator) - << (K == Kind::ArraySubscript) << (OOK == Sema::OOK_Macro); - }; - // FIXME: This loop leaks the index expressions on error. while (true) { if (Tok.is(tok::period)) { @@ -2648,9 +2631,9 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } - DiagExt(Comps.back().LocStart, Kind::MemberAccess); Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); Comps.back().LocEnd = ConsumeToken(); + } else if (Tok.is(tok::l_square)) { if (CheckProhibitedCXX11Attribute()) return ExprError(); @@ -2666,7 +2649,6 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { SkipUntil(tok::r_paren, StopAtSemi); return Res; } - DiagExt(Comps.back().LocStart, Kind::ArraySubscript); Comps.back().U.E = Res.get(); ST.consumeClose(); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0fd68c5..baadaf3 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -16593,7 +16593,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, - OffsetOfKind OOK, SkipBodyInfo *SkipBody) { + SkipBodyInfo *SkipBody) { // If this is not a definition, it must have a name. IdentifierInfo *OrigName = Name; assert((Name != nullptr || TUK == TUK_Definition) && @@ -17366,16 +17366,10 @@ CreateNewDecl: cast_or_null(PrevDecl)); } - if (OOK != OOK_Outside && TUK == TUK_Definition && !getLangOpts().CPlusPlus) { - Diag(New->getLocation(), diag::ext_type_defined_in_offsetof) - << (OOK == OOK_Macro) << New->getSourceRange(); - Invalid = true; - } - // C++11 [dcl.type]p3: // A type-specifier-seq shall not define a class or enumeration [...]. - if (!Invalid && getLangOpts().CPlusPlus && - (IsTypeSpecifier || IsTemplateParamOrArg) && TUK == TUK_Definition) { + if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) && + TUK == TUK_Definition) { Diag(New->getLocation(), diag::err_type_defined_in_type_specifier) << Context.getTagDeclType(New); Invalid = true; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index cf1242b..f66b8b7 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -16974,15 +16974,15 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, if (SS.isEmpty()) { bool Owned = false; bool IsDependent = false; - return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, Attr, - AS_public, + return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, + Attr, AS_public, /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned, IsDependent, /*ScopedEnumKWLoc=*/SourceLocation(), /*ScopedEnumUsesClassTag=*/false, /*UnderlyingType=*/TypeResult(), /*IsTypeSpecifier=*/false, - /*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside); + /*IsTemplateParamOrArg=*/false); } NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 1b30116..8466ed0 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -10181,12 +10181,13 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, bool Owned = false; bool IsDependent = false; - Decl *TagD = ActOnTag( - S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, NameLoc, Attr, AS_none, - /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned, - IsDependent, SourceLocation(), false, TypeResult(), - /*IsTypeSpecifier*/ false, - /*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside); + Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference, + KWLoc, SS, Name, NameLoc, Attr, AS_none, + /*ModulePrivateLoc=*/SourceLocation(), + MultiTemplateParamsArg(), Owned, IsDependent, + SourceLocation(), false, TypeResult(), + /*IsTypeSpecifier*/false, + /*IsTemplateParamOrArg*/false); assert(!IsDependent && "explicit instantiation of dependent name not yet handled"); if (!TagD) diff --git a/clang/test/C/C2x/n2350.c b/clang/test/C/C2x/n2350.c deleted file mode 100644 index 93ab507..0000000 --- a/clang/test/C/C2x/n2350.c +++ /dev/null @@ -1,74 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify=silent %s -// RUN: %clang_cc1 -fsyntax-only -verify=cpp -x c++ %s -// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -verify %s -// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c89 -verify %s -// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c99 -verify %s -// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c11 -verify %s -// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c17 -verify %s -// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c2x -verify %s - -// silent-no-diagnostics - -// Reject definitions in __builtin_offsetof -// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm -int simple(void) { - return __builtin_offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \ - expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}} - { - int a; - struct B // expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}} - { - int c; - int d; - } x; - }, a); -} - -int anonymous_struct(void) { - return __builtin_offsetof(struct // cpp-error-re {{'(unnamed struct at {{.*}})' cannot be defined in a type specifier}} \ - expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}} - { - int a; - int b; - }, a); -} - -int struct_in_second_param(void) { - struct A { - int a, b; - int x[20]; - }; - return __builtin_offsetof(struct A, x[sizeof(struct B{int a;})]); // cpp-error {{'B' cannot be defined in a type specifier}} \ - expected-warning {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} -} - - -#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) - - -int macro(void) { - return offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \ - expected-warning 2 {{defining a type within 'offsetof' is a Clang extension}} - { - int a; - struct B // verifier seems to think the error is emitted by the macro - // In fact the location of the error is "B" on the line above - { - int c; - int d; - } x; - }, a); -} - -#undef offsetof - -#define offsetof(TYPE, MEMBER) (&((TYPE *)0)->MEMBER) - -// no warning for traditional offsetof as a function-like macro -int * macro_func(void) { - return offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} - { - int a; - int b; - }, a); -} diff --git a/clang/test/C/drs/dr4xx.c b/clang/test/C/drs/dr4xx.c index 3ad9b17..768897c 100644 --- a/clang/test/C/drs/dr4xx.c +++ b/clang/test/C/drs/dr4xx.c @@ -337,13 +337,12 @@ void dr496(void) { * because it references an array of another struct. Clang calculates the * correct offset to each of those fields. */ - _Static_assert(__builtin_offsetof(struct B, a.n) == 0, ""); /* expected-warning {{using a member access expression within '__builtin_offsetof' is a Clang extension}} */ + _Static_assert(__builtin_offsetof(struct B, a.n) == 0, ""); /* First int below is for 'n' and the second int is for 'a[0]'; this presumes * there is no padding involved. */ - _Static_assert(__builtin_offsetof(struct B, a.a[1]) == sizeof(int) + sizeof(int), ""); /* expected-warning {{using a member access expression within '__builtin_offsetof' is a Clang extension}} - expected-warning {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} - */ + _Static_assert(__builtin_offsetof(struct B, a.a[1]) == sizeof(int) + sizeof(int), ""); + /* However, we do not support using the -> operator to access a member, even * if that would be a valid expression. FIXME: GCC accepts this, perhaps we * should as well. @@ -353,10 +352,11 @@ void dr496(void) { */ /* The DR asked a question about whether defining a new type within offsetof - * is allowed. C2x N2350 made this explicitly undefined behavior, but GCC and - * Clang both support it as an extension. + * is allowed. C2x N2350 made this explicitly undefined behavior, but Clang + * has always supported defining a type in this location, and GCC also + * supports it. */ - (void)__builtin_offsetof(struct S { int a; }, a); /* expected-warning{{defining a type within '__builtin_offsetof' is a Clang extension}} */ + (void)__builtin_offsetof(struct S { int a; }, a); } /* WG14 DR499: yes diff --git a/clang/test/CXX/drs/dr4xx.cpp b/clang/test/CXX/drs/dr4xx.cpp index 476d80e..3617af8 100644 --- a/clang/test/CXX/drs/dr4xx.cpp +++ b/clang/test/CXX/drs/dr4xx.cpp @@ -687,9 +687,9 @@ namespace dr447 { // dr447: yes U<__builtin_offsetof(A, n)>::type a; U<__builtin_offsetof(T, n)>::type b; // expected-error +{{}} expected-warning 0+{{}} // as an extension, we allow the member-designator to include array indices - g(__builtin_offsetof(A, a[0])).h(); // expected-error {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} - g(__builtin_offsetof(A, a[N])).h(); // expected-error {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} - U<__builtin_offsetof(A, a[0])>::type c; // expected-error {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}} + g(__builtin_offsetof(A, a[0])).h(); + g(__builtin_offsetof(A, a[N])).h(); + U<__builtin_offsetof(A, a[0])>::type c; U<__builtin_offsetof(A, a[N])>::type d; // expected-error +{{}} expected-warning 0+{{}} } } diff --git a/clang/test/Parser/declarators.c b/clang/test/Parser/declarators.c index 3af0981..464fafe 100644 --- a/clang/test/Parser/declarators.c +++ b/clang/test/Parser/declarators.c @@ -80,6 +80,10 @@ struct test9 { struct test10 { int a; } static test10x; struct test11 { int a; } const test11x; +// PR6216 +void test12(void) { + (void)__builtin_offsetof(struct { char c; int i; }, i); +} // rdar://7608537 struct test13 { int a; } (test13x); diff --git a/clang/test/SemaCXX/offsetof.cpp b/clang/test/SemaCXX/offsetof.cpp index 39ea380..c4b288a 100644 --- a/clang/test/SemaCXX/offsetof.cpp +++ b/clang/test/SemaCXX/offsetof.cpp @@ -83,18 +83,3 @@ struct Derived : virtual Base { expected-error {{invalid application of 'offsetof' to a field of a virtual base}} }; } - -int test_definition(void) { - return __builtin_offsetof(struct A // expected-error {{'A' cannot be defined in a type specifier}} - { - int a; - struct B // FIXME: error diagnostic message for nested definitions - // https://reviews.llvm.org/D133574 - // fixme-error{{'A' cannot be defined in '__builtin_offsetof'}} - { - int c; - int d; - }; - B x; - }, a); -} -- 2.7.4