[llvm-branch-commits] [clang] 590e146 - Fix assertion failure due to incorrect dependence bits on a DeclRefExpr
Richard Smith via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Dec 7 18:53:26 PST 2020
Author: Richard Smith
Date: 2020-12-07T18:48:38-08:00
New Revision: 590e14653252faa97c2a32ba38aeef05ec681f9b
URL: https://github.com/llvm/llvm-project/commit/590e14653252faa97c2a32ba38aeef05ec681f9b
DIFF: https://github.com/llvm/llvm-project/commit/590e14653252faa97c2a32ba38aeef05ec681f9b.diff
LOG: Fix assertion failure due to incorrect dependence bits on a DeclRefExpr
that can only be set correctly after instantiating the initializer for a
variable.
Added:
Modified:
clang/include/clang/AST/Expr.h
clang/lib/AST/Expr.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/recovery-expr-type.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 3ea2817f1926..c8d87ec48a3f 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -1284,7 +1284,7 @@ class DeclRefExpr final
ValueDecl *getDecl() { return D; }
const ValueDecl *getDecl() const { return D; }
- void setDecl(ValueDecl *NewD) { D = NewD; }
+ void setDecl(ValueDecl *NewD);
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc);
@@ -3167,7 +3167,7 @@ class MemberExpr final
/// The returned declaration will be a FieldDecl or (in C++) a VarDecl (for
/// static data members), a CXXMethodDecl, or an EnumConstantDecl.
ValueDecl *getMemberDecl() const { return MemberDecl; }
- void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
+ void setMemberDecl(ValueDecl *D);
/// Retrieves the declaration found by lookup.
DeclAccessPair getFoundDecl() const {
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index f55ee20f2476..1bd032a04a51 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -486,6 +486,11 @@ DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context,
return new (Mem) DeclRefExpr(EmptyShell());
}
+void DeclRefExpr::setDecl(ValueDecl *NewD) {
+ D = NewD;
+ setDependence(computeDependence(this, NewD->getASTContext()));
+}
+
SourceLocation DeclRefExpr::getBeginLoc() const {
if (hasQualifier())
return getQualifierLoc().getBeginLoc();
@@ -1572,6 +1577,11 @@ MemberExpr *MemberExpr::CreateEmpty(const ASTContext &Context,
return new (Mem) MemberExpr(EmptyShell());
}
+void MemberExpr::setMemberDecl(ValueDecl *D) {
+ MemberDecl = D;
+ setDependence(computeDependence(this));
+}
+
SourceLocation MemberExpr::getBeginLoc() const {
if (isImplicitAccess()) {
if (hasQualifier())
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 738fe87d37b4..859960d13007 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18152,6 +18152,13 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
SemaRef.runWithSufficientStackSpace(PointOfInstantiation, [&] {
SemaRef.InstantiateVariableDefinition(PointOfInstantiation, Var);
});
+
+ // Re-set the member to trigger a recomputation of the dependence bits
+ // for the expression.
+ if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E))
+ DRE->setDecl(DRE->getDecl());
+ else if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
+ ME->setMemberDecl(ME->getMemberDecl());
} else if (FirstInstantiation ||
isa<VarTemplateSpecializationDecl>(Var)) {
// FIXME: For a specialization of a variable template, we don't
@@ -18286,6 +18293,9 @@ static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
}
/// Perform reference-marking and odr-use handling for a DeclRefExpr.
+///
+/// Note, this may change the dependence of the DeclRefExpr, and so needs to be
+/// handled with care if the DeclRefExpr is not newly-created.
void Sema::MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base) {
// TODO: update this with DR# once a defect report is filed.
// C++11 defect. The address of a pure member should not be an ODR use, even
@@ -18412,6 +18422,10 @@ class EvaluatedExprMarker : public UsedDeclVisitor<EvaluatedExprMarker> {
if (VD->hasLocalStorage())
return;
}
+
+ // FIXME: This can trigger the instantiation of the initializer of a
+ // variable, which can cause the expression to become value-dependent
+ // or error-dependent. Do we need to propagate the new dependence bits?
S.MarkDeclRefReferenced(E);
}
diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp
index f4691b47ab6d..ed18b7f262cd 100644
--- a/clang/test/SemaCXX/recovery-expr-type.cpp
+++ b/clang/test/SemaCXX/recovery-expr-type.cpp
@@ -109,3 +109,10 @@ auto f(); // expected-note {{candidate function not viable}}
// verify no crash on evaluating the size of undeduced auto type.
static_assert(sizeof(f(1)), ""); // expected-error {{no matching function for call to 'f'}}
}
+
+namespace test10 {
+// Ensure we don't assert here.
+int f(); // expected-note {{candidate}}
+template<typename T> const int k = f(T()); // expected-error {{no matching function}}
+static_assert(k<int> == 1, ""); // expected-note {{instantiation of}}
+}
More information about the llvm-branch-commits
mailing list