[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 15 09:37:43 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;
+ }
----------------
AaronBallman wrote:
Test case to consider involving indirect fields:
```
struct S {
union {
volatile int i;
};
int j;
};
constexpr struct S s = {}; // Error
```
https://godbolt.org/z/rE15hqGxa
https://github.com/llvm/llvm-project/pull/73099
More information about the cfe-commits
mailing list