Skip to content

Commit 6603052

Browse files
committedMar 1, 2018
[CFG] [analyzer] Recall that we only skip NoOp casts in construction contexts.
For now. We should also add support for ConstructorConversion casts as presented in the attached test case, but this requires more changes because AST around them seems different. The check was originally present but was accidentally lost during r326021. Differential Revision: https://reviews.llvm.org/D43840 llvm-svn: 326402
1 parent 852bd5c commit 6603052

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed
 

‎clang/lib/Analysis/CFG.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,9 @@ void CFGBuilder::findConstructionContexts(
12001200
}
12011201
case Stmt::ImplicitCastExprClass: {
12021202
auto *Cast = cast<ImplicitCastExpr>(Child);
1203-
findConstructionContexts(Layer, Cast->getSubExpr());
1203+
// TODO: We need to support CK_ConstructorConversion, maybe other kinds?
1204+
if (Cast->getCastKind() == CK_NoOp)
1205+
findConstructionContexts(Layer, Cast->getSubExpr());
12041206
break;
12051207
}
12061208
case Stmt::CXXBindTemporaryExprClass: {

‎clang/test/Analysis/cfg-rich-constructors.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -484,4 +484,35 @@ void referenceWithFunctionalCast() {
484484
void constructorInTernaryCondition() {
485485
const D &d = D(1) ? D(2) : D(3);
486486
}
487+
487488
} // end namespace temporary_object_expr_with_dtors
489+
490+
namespace implicit_constructor_conversion {
491+
492+
class A {};
493+
A get();
494+
495+
class B {
496+
public:
497+
B(const A &);
498+
~B() {}
499+
};
500+
501+
// FIXME: Find construction context for the implicit constructor conversion.
502+
// CHECK: void implicitConstructionConversionFromFunctionValue()
503+
// CHECK: 1: get
504+
// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conver
505+
// CHECK-NEXT: 3: [B1.2]()
506+
// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
507+
// CHECK-NEXT: 5: [B1.4]
508+
// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, class implicit_constructor_conversion::B)
509+
// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_convers
510+
// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B)
511+
// CHECK-NEXT: 9: [B1.8]
512+
// CHECK-NEXT: 10: const implicit_constructor_conversion::B &b = get();
513+
// CHECK-NEXT: 11: [B1.10].~B() (Implicit destructor)
514+
void implicitConstructionConversionFromFunctionValue() {
515+
const B &b = get(); // no-crash
516+
}
517+
518+
} // end namespace implicit_constructor_conversion

0 commit comments

Comments
 (0)
Please sign in to comment.