inclyc updated this revision to Diff 459458.
inclyc added a comment.
Use declaration context
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D133574/new/
https://reviews.llvm.org/D133574
Files:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/DeclSpec.h
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Parse/ParseExpr.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaType.cpp
clang/test/Parser/declarators.c
clang/test/Sema/offsetof.c
Index: clang/test/Sema/offsetof.c
===================================================================
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
}
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+ return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}}
+ {
+ int a;
+ struct B // no-error, struct B is not defined within __builtin_offsetof directly
+ {
+ int c;
+ int d;
+ } x;
+ }, a);
+}
Index: clang/test/Parser/declarators.c
===================================================================
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
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);
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -3584,6 +3584,7 @@
[[fallthrough]];
case DeclaratorContext::TypeName:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
Error = 15; // Generic
break;
case DeclaratorContext::File:
@@ -3695,6 +3696,7 @@
case DeclaratorContext::TemplateArg:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
DiagID = diag::err_type_defined_in_type_specifier;
break;
case DeclaratorContext::Prototype:
@@ -4784,6 +4786,7 @@
case DeclaratorContext::FunctionalCast:
case DeclaratorContext::RequiresExpr:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
// Don't infer in these contexts.
break;
}
@@ -5836,6 +5839,7 @@
case DeclaratorContext::TemplateArg:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
// FIXME: We may want to allow parameter packs in block-literal contexts
// in the future.
S.Diag(D.getEllipsisLoc(),
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16254,7 +16254,7 @@
SourceLocation ScopedEnumKWLoc,
bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinBuiltinOffsetof) {
// If this is not a definition, it must have a name.
IdentifierInfo *OrigName = Name;
assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17027,6 +17027,12 @@
cast_or_null<RecordDecl>(PrevDecl));
}
+ if (IsWithinBuiltinOffsetof && TUK == TUK_Definition) {
+ Diag(New->getLocation(), diag::err_type_defined_in_offsetof)
+ << Context.getTagDeclType(New);
+ Invalid = true;
+ }
+
// C++11 [dcl.type]p3:
// A type-specifier-seq shall not define a class or enumeration [...].
if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2579,7 +2579,8 @@
}
case tok::kw___builtin_offsetof: {
SourceLocation TypeLoc = Tok.getLocation();
- TypeResult Ty = ParseTypeName();
+ TypeResult Ty =
+ ParseTypeName(/*Range*/ nullptr, DeclaratorContext::OffsetOf);
if (Ty.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
Index: clang/lib/Parse/ParseDeclCXX.cpp
===================================================================
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2030,7 +2030,7 @@
DSC == DeclSpecContext::DSC_type_specifier,
DSC == DeclSpecContext::DSC_template_param ||
DSC == DeclSpecContext::DSC_template_type_arg,
- &SkipBody);
+ &SkipBody, DSC == DeclSpecContext::DSC_offsetof);
// If ActOnTag said the type was dependent, try again with the
// less common call.
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -2893,6 +2893,8 @@
return DeclSpecContext::DSC_alias_declaration;
if (Context == DeclaratorContext::Association)
return DeclSpecContext::DSC_association;
+ if (Context == DeclaratorContext::OffsetOf)
+ return DeclSpecContext::DSC_offsetof;
return DeclSpecContext::DSC_normal;
}
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3273,7 +3273,8 @@
bool &IsDependent, SourceLocation ScopedEnumKWLoc,
bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody = nullptr);
+ SkipBodyInfo *SkipBody = nullptr,
+ bool IsWithinBuiltinOffsetof = false);
Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
unsigned TagSpec, SourceLocation TagLoc,
Index: clang/include/clang/Sema/DeclSpec.h
===================================================================
--- clang/include/clang/Sema/DeclSpec.h
+++ clang/include/clang/Sema/DeclSpec.h
@@ -1798,7 +1798,8 @@
AliasDecl, // C++11 alias-declaration.
AliasTemplate, // C++11 alias-declaration template.
RequiresExpr, // C++2a requires-expression.
- Association // C11 _Generic selection expression association.
+ Association, // C11 _Generic selection expression association.
+ OffsetOf // Declaration within __builtin_offsetof
};
/// Information about one declarator, including the parsed type
@@ -2065,6 +2066,7 @@
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::RequiresExpr:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
return true;
}
llvm_unreachable("unknown context kind!");
@@ -2105,6 +2107,7 @@
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2149,6 +2152,7 @@
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2206,6 +2210,7 @@
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::RequiresExpr:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2429,6 +2434,7 @@
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::RequiresExpr:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2464,6 +2470,7 @@
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::RequiresExpr:
case DeclaratorContext::Association:
+ case DeclaratorContext::OffsetOf:
return false;
case DeclaratorContext::Block:
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -2200,7 +2200,8 @@
DSC_template_type_arg, // template type argument context
DSC_objc_method_result, // ObjC method result context, enables 'instancetype'
DSC_condition, // condition declaration context
- DSC_association // A _Generic selection expression's type association
+ DSC_association, // A _Generic selection expression's type association
+ DSC_offsetof // Within __builtin_offsetof, reject definitions here
};
/// Is this a context in which we are parsing just a type-specifier (or
@@ -2213,6 +2214,7 @@
case DeclSpecContext::DSC_top_level:
case DeclSpecContext::DSC_objc_method_result:
case DeclSpecContext::DSC_condition:
+ case DeclSpecContext::DSC_offsetof:
return false;
case DeclSpecContext::DSC_template_type_arg:
@@ -2251,6 +2253,7 @@
case DeclSpecContext::DSC_top_level:
case DeclSpecContext::DSC_alias_declaration:
case DeclSpecContext::DSC_objc_method_result:
+ case DeclSpecContext::DSC_offsetof:
return AllowDefiningTypeSpec::Yes;
case DeclSpecContext::DSC_condition:
@@ -2277,6 +2280,7 @@
case DeclSpecContext::DSC_normal:
case DeclSpecContext::DSC_class:
case DeclSpecContext::DSC_top_level:
+ case DeclSpecContext::DSC_offsetof:
return true;
case DeclSpecContext::DSC_alias_declaration:
@@ -2303,6 +2307,7 @@
case DeclSpecContext::DSC_condition:
case DeclSpecContext::DSC_type_specifier:
case DeclSpecContext::DSC_association:
+ case DeclSpecContext::DSC_offsetof:
return true;
case DeclSpecContext::DSC_objc_method_result:
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1646,6 +1646,8 @@
"%0 cannot be defined in a condition">;
def err_type_defined_in_enum : Error<
"%0 cannot be defined in an enumeration">;
+def err_type_defined_in_offsetof : Error<
+ "%0 cannot be defined in '__builtin_offsetof'">;
def note_pure_virtual_function : Note<
"unimplemented pure virtual method %0 in %1">;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -191,6 +191,7 @@
- Adjusted ``-Wformat`` warnings according to `WG14 N2562 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf>`_.
Clang will now consider default argument promotions in printf, and remove unnecessary warnings.
Especially ``int`` argument with specifier ``%hhd`` and ``%hd``.
+- Reject type definitions in the ``type`` argument of ``__builtin_offsetof`` according to `WG14 N2350 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm>`_.
C2x Feature Support
-------------------
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits