From: Haojian Wu Date: Tue, 21 Jul 2020 07:39:44 +0000 (+0200) Subject: [clang] Set the error-bit for ill-formed semantic InitListExpr. X-Git-Tag: llvmorg-13-init~17322 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=566b49884d69f88147c1ca18fd4512f73a3c15e3;p=platform%2Fupstream%2Fllvm.git [clang] Set the error-bit for ill-formed semantic InitListExpr. When a semantic checking fails on a syntactic InitListExpr, we will get an ill-formed semantic InitListExpr (e.g. some inits are nullptr), using this semantic InitListExpr in clang (without setting the err-bits) is crashy. Differential Revision: https://reviews.llvm.org/D84140 --- diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index 19ab6d6..636e5d9 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -957,6 +957,16 @@ TEST(Hover, NoHover) { template void foo() { (void)[[size^of]](T); })cpp", + R"cpp(// should not crash on invalid semantic form of init-list-expr. + /*error-ok*/ + struct Foo { + int xyz = 0; + }; + class Bar {}; + constexpr Foo s = ^{ + .xyz = Bar(), + }; + )cpp", // literals "auto x = t^rue;", "auto x = '^A';", diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h index 14a7ffa..ca96b65 100644 --- a/clang/include/clang/AST/DependenceFlags.h +++ b/clang/include/clang/AST/DependenceFlags.h @@ -41,6 +41,7 @@ struct ExprDependenceScope { TypeInstantiation = Type | Instantiation, ValueInstantiation = Value | Instantiation, TypeValueInstantiation = Type | Value | Instantiation, + ErrorDependent = Error | ValueInstantiation, LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) }; diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index c13b971..ea8f688 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4690,6 +4690,13 @@ public: setDependence(getDependence() | expr->getDependence()); } + /// Mark the semantic form of the InitListExpr as error when the semantic + /// analysis fails. + void markError() { + assert(isSemanticForm()); + setDependence(getDependence() | ExprDependence::ErrorDependent); + } + /// Reserve space for some number of initializers. void reserveInits(const ASTContext &C, unsigned NumInits); diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index 2333993..c3a2090 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -502,7 +502,7 @@ ExprDependence clang::computeDependence(RecoveryExpr *E) { // dependent type), or the type is known and dependent, or it has // type-dependent subexpressions. auto D = toExprDependence(E->getType()->getDependence()) | - ExprDependence::ValueInstantiation | ExprDependence::Error; + ExprDependence::ErrorDependent; // FIXME: remove the type-dependent bit from subexpressions, if the // RecoveryExpr has a non-dependent type. for (auto *S : E->subExpressions()) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index eb07de65..e2f67e9 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -962,6 +962,8 @@ InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity, FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass, nullptr, 0); } + if (hadError && FullyStructuredList) + FullyStructuredList->markError(); } int InitListChecker::numArrayElements(QualType DeclType) {