[llvm-branch-commits] [clang] 84f3164 - Stop diagnosing member and array access in offsetof as an extension

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jan 27 20:42:59 PST 2023


Author: Aaron Ballman
Date: 2023-01-27T20:41:31-08:00
New Revision: 84f3164c1d9ce024f59221dcfbc8ab050de73748

URL: https://github.com/llvm/llvm-project/commit/84f3164c1d9ce024f59221dcfbc8ab050de73748
DIFF: https://github.com/llvm/llvm-project/commit/84f3164c1d9ce024f59221dcfbc8ab050de73748.diff

LOG: Stop diagnosing member and array access in offsetof as an extension

This was a mistake from e7300e75b51a7e7d4e81975b4be7a6c65f9a8286
(https://reviews.llvm.org/D133574) caused by us accidentally tracking
an older copy of the C DR list for DR496. The text in
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2396.htm#dr_496 makes
it clear that subobjects are allowed, which means member and array
access expressions are allowed.

This backs out the changes from the previous commit that relate to this
diagnostic.

(cherry picked from commit 63d6b8be6cf2422228a1a8800d85a11be469c6e2)

Added: 
    

Modified: 
    clang/docs/LanguageExtensions.rst
    clang/include/clang/Basic/DiagnosticParseKinds.td
    clang/lib/Parse/ParseExpr.cpp
    clang/test/C/C2x/n2350.c
    clang/test/C/drs/dr4xx.c
    clang/test/CXX/drs/dr4xx.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 2e99a6072a94d..75fcd418e7ea2 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -2386,21 +2386,19 @@ calculates the offset (in bytes) to a given member of the given type.
 
   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
+  const int ext2 = __builtin_offsetof(struct S, t.f[1]);
 
 **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:
+``type-name``. Clang extends the required standard functionality in the
+following way:
 
 * 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)``.
 

diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index c367a34b762b7..36d4bc2a700d8 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<GNUOffsetofExtensions>;
-
 let CategoryName = "Generics Issue" in {
 
 def err_objc_expected_type_parameter : Error<

diff  --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 392ed29467a97..66d937ac5742d 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2629,12 +2629,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,7 +2642,6 @@ 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)) {
@@ -2666,7 +2659,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/test/C/C2x/n2350.c b/clang/test/C/C2x/n2350.c
index 93ab5070b6c63..2f738488a3742 100644
--- a/clang/test/C/C2x/n2350.c
+++ b/clang/test/C/C2x/n2350.c
@@ -38,8 +38,7 @@ int struct_in_second_param(void) {
     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}}
+  return __builtin_offsetof(struct A, x[sizeof(struct B{int a;})]); // cpp-error {{'B' cannot be defined in a type specifier}}
 }
 
 

diff  --git a/clang/test/C/drs/dr4xx.c b/clang/test/C/drs/dr4xx.c
index 3ad9b17a83df1..5c5349aa7c140 100644
--- a/clang/test/C/drs/dr4xx.c
+++ b/clang/test/C/drs/dr4xx.c
@@ -331,19 +331,13 @@ void dr496(void) {
   struct B { struct A a; };
   struct C { struct A a[1]; };
 
-  /* The standard does not require either of these examples to work, but we
-   * support them just the same. The first one is invalid because it's
-   * referencing a member of a 
diff erent struct, and the second one is invalid
-   * 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}} */
+  /* Array access & member access expressions are now valid. */
+  _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.

diff  --git a/clang/test/CXX/drs/dr4xx.cpp b/clang/test/CXX/drs/dr4xx.cpp
index 476d80ef0720d..3617af8b683c0 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<int>(); // expected-error {{using an array subscript expression within '__builtin_offsetof' is a Clang extension}}
-    g(__builtin_offsetof(A, a[N])).h<int>(); // 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<int>();
+    g(__builtin_offsetof(A, a[N])).h<int>();
+    U<__builtin_offsetof(A, a[0])>::type c;
     U<__builtin_offsetof(A, a[N])>::type d; // expected-error +{{}} expected-warning 0+{{}}
   }
 }


        


More information about the llvm-branch-commits mailing list