================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits