inclyc updated this revision to Diff 459634.
inclyc added a comment.

git-clang-format


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
@@ -16257,7 +16257,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) &&
@@ -17030,6 +17030,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
@@ -2190,17 +2190,19 @@
   /// out, there are other significant restrictions on specifiers than
   /// would be best implemented in the parser.
   enum class DeclSpecContext {
-    DSC_normal, // normal context
-    DSC_class,  // class context, enables 'friend'
+    DSC_normal,         // normal context
+    DSC_class,          // class context, enables 'friend'
     DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
     DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
-    DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration
-    DSC_top_level, // top-level/namespace declaration context
-    DSC_template_param, // template parameter context
-    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_alias_declaration,  // C++11 type-specifier-seq in an alias-declaration
+    DSC_top_level,          // top-level/namespace declaration context
+    DSC_template_param,     // template parameter context
+    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_offsetof     // Within __builtin_offsetof, reject definitions here
   };
 
   /// Is this a context in which we are parsing just a type-specifier (or
@@ -2220,6 +2222,7 @@
     case DeclSpecContext::DSC_trailing:
     case DeclSpecContext::DSC_alias_declaration:
     case DeclSpecContext::DSC_association:
+    case DeclSpecContext::DSC_offsetof:
       return true;
     }
     llvm_unreachable("Missing DeclSpecContext case");
@@ -2259,6 +2262,7 @@
 
     case DeclSpecContext::DSC_template_type_arg:
     case DeclSpecContext::DSC_type_specifier:
+    case DeclSpecContext::DSC_offsetof:
       return AllowDefiningTypeSpec::NoButErrorRecovery;
 
     case DeclSpecContext::DSC_association:
@@ -2287,6 +2291,7 @@
     case DeclSpecContext::DSC_type_specifier:
     case DeclSpecContext::DSC_trailing:
     case DeclSpecContext::DSC_association:
+    case DeclSpecContext::DSC_offsetof:
       return false;
     }
     llvm_unreachable("Missing DeclSpecContext case");
@@ -2303,6 +2308,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
@@ -202,6 +202,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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to