[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 26 09:15:23 PST 2024


================
@@ -8569,6 +8571,37 @@ static bool checkForConflictWithNonVisibleExternC(Sema &S, const T *ND,
   return false;
 }
 
+static bool CheckC23ConstexprVarType(Sema &SemaRef, SourceLocation VarLoc,
+                                     QualType T) {
+
+  if (T->isVariableArrayType()) {
+    SemaRef.Diag(VarLoc, diag::err_c23_constexpr_invalid_type) << T;
+    return true;
+  }
+
+  // Arrays are qualified by their element type, so get the base type (this
+  // works on non-arrays as well).
+  T = SemaRef.Context.getBaseElementType(T);
+
+  // C23 6.7.1p4: An object declared with storage-class specifier constexpr or
+  // any of its members, even recursively, shall not have an atomic type, or a
+  // variably modified type, or a type that is volatile or restrict qualified.
+  if (T->isAtomicType() || T.isVolatileQualified() || T.isRestrictQualified()) {
+    SemaRef.Diag(VarLoc, diag::err_c23_constexpr_invalid_type) << T;
+    return true;
+  }
+
+  if (T->isRecordType()) {
+    const RecordDecl *RD = T->getAsRecordDecl();
+    if (llvm::any_of(RD->fields(), [&SemaRef, VarLoc](const FieldDecl *F) {
+          return CheckC23ConstexprVarType(SemaRef, VarLoc, F->getType());
+        }))
+      return true;
+  }
----------------
Fznamznon wrote:

Added. Lines 130-137 in test/Sema/constexpr.c.

https://github.com/llvm/llvm-project/pull/73099


More information about the cfe-commits mailing list