forked from OSchip/llvm-project
Stop double visiting some expressions during self reference checking.
Originally, self reference checking made a double pass over some expressions to handle reference type checking. Now, allow HandleValue to also check reference types, and fallback to Visit for unhandled expressions. llvm-svn: 217203
This commit is contained in:
parent
c4b4253f7c
commit
2a07c96737
|
@ -8207,8 +8207,6 @@ namespace {
|
|||
// For conditional operators, the cast can be outside the conditional
|
||||
// operator if both expressions are DeclRefExpr's.
|
||||
void HandleValue(Expr *E) {
|
||||
if (isReferenceType)
|
||||
return;
|
||||
E = E->IgnoreParens();
|
||||
if (DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(E)) {
|
||||
HandleDeclRefExpr(DRE);
|
||||
|
@ -8223,6 +8221,7 @@ namespace {
|
|||
|
||||
if (BinaryConditionalOperator *BCO =
|
||||
dyn_cast<BinaryConditionalOperator>(E)) {
|
||||
Visit(BCO->getCond());
|
||||
HandleValue(BCO->getFalseExpr());
|
||||
return;
|
||||
}
|
||||
|
@ -8250,10 +8249,12 @@ namespace {
|
|||
HandleDeclRefExpr(DRE);
|
||||
return;
|
||||
}
|
||||
|
||||
Visit(E);
|
||||
}
|
||||
|
||||
// Reference types are handled here since all uses of references are
|
||||
// bad, not just r-value uses.
|
||||
// Reference types not handled in HandleValue are handled here since all
|
||||
// uses of references are bad, not just r-value uses.
|
||||
void VisitDeclRefExpr(DeclRefExpr *E) {
|
||||
if (isReferenceType)
|
||||
HandleDeclRefExpr(E);
|
||||
|
@ -8261,8 +8262,10 @@ namespace {
|
|||
|
||||
void VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
||||
if (E->getCastKind() == CK_LValueToRValue ||
|
||||
(isRecordType && E->getCastKind() == CK_NoOp))
|
||||
(isRecordType && E->getCastKind() == CK_NoOp)) {
|
||||
HandleValue(E->getSubExpr());
|
||||
return;
|
||||
}
|
||||
|
||||
Inherited::VisitImplicitCastExpr(E);
|
||||
}
|
||||
|
@ -8329,6 +8332,7 @@ namespace {
|
|||
if (FunctionDecl *FD = E->getDirectCallee()) {
|
||||
if (FD->getIdentifier() && FD->getIdentifier()->isStr("move")) {
|
||||
HandleValue(E->getArg(0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8336,6 +8340,14 @@ namespace {
|
|||
Inherited::VisitCallExpr(E);
|
||||
}
|
||||
|
||||
// A custom visitor for BinaryConditionalOperator is needed because the
|
||||
// regular visitor would check the condition and true expression separately
|
||||
// but both point to the same place giving duplicate diagnostics.
|
||||
void VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
|
||||
Visit(E->getCond());
|
||||
Visit(E->getFalseExpr());
|
||||
}
|
||||
|
||||
void HandleDeclRefExpr(DeclRefExpr *DRE) {
|
||||
Decl* ReferenceDecl = DRE->getDecl();
|
||||
if (OrigDecl != ReferenceDecl) return;
|
||||
|
|
|
@ -566,6 +566,12 @@ namespace references {
|
|||
int &e = d ?: e; // expected-warning{{reference 'e' is not yet bound to a value when used within its own initialization}}
|
||||
int &f = f ?: d; // expected-warning{{reference 'f' is not yet bound to a value when used within its own initialization}}
|
||||
|
||||
int &return_ref1(int);
|
||||
int &return_ref2(int&);
|
||||
|
||||
int &g = return_ref1(g); // expected-warning{{reference 'g' is not yet bound to a value when used within its own initialization}}
|
||||
int &h = return_ref2(h); // expected-warning{{reference 'h' is not yet bound to a value when used within its own initialization}}
|
||||
|
||||
struct S {
|
||||
S() : a(a) {} // expected-warning{{reference 'a' is not yet bound to a value when used here}}
|
||||
int &a;
|
||||
|
|
Loading…
Reference in New Issue