[PATCH] D49627: [CFG] [analyzer] Constructors of member CXXOperatorCallExpr's argument 0 are not argument constructors.
Artem Dergachev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 20 17:46:00 PDT 2018
NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet, rnkovacs, baloghadamsoftware.
Herald added subscribers: cfe-commits, mikhail.ramalho.
Because `CXXOperatorCallExpr`'s argument 0 is the `this`-argument of the operator if the operator is a member. This doesn't correspond to operator declaration parameters.
Do not provide argument construction context for such arguments. For the remaining arguments, provide a context, even though argument index still doesn't match parameter index; the user would, unfortunately, need to work around that, as we can't satisfy both.
Actually supporting such this-argument construction contexts would address the FIXME that we've added in https://reviews.llvm.org/D32642?id=153023#inline-426950 but this patch doesn't go that far.
Repository:
rC Clang
https://reviews.llvm.org/D49627
Files:
include/clang/Analysis/ConstructionContext.h
lib/Analysis/CFG.cpp
test/Analysis/cfg-rich-constructors.cpp
Index: test/Analysis/cfg-rich-constructors.cpp
===================================================================
--- test/Analysis/cfg-rich-constructors.cpp
+++ test/Analysis/cfg-rich-constructors.cpp
@@ -960,3 +960,37 @@
C c = C();
}
} // namespace copy_elision_with_extra_arguments
+
+
+namespace operators {
+class C {
+public:
+ C(int);
+ C &operator+(C Other);
+};
+
+// FIXME: Find construction context for the this-argument of the operator.
+// CHECK: void testOperators()
+// CHECK: [B1]
+// CHECK-NEXT: 1: operator+
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class operators::C &(*)(class operators::C))
+// CHECK-NEXT: 3: 1
+// CXX11-NEXT: 4: [B1.3] (CXXConstructExpr, class operators::C)
+// CXX11-NEXT: 5: operators::C([B1.4]) (CXXFunctionalCastExpr, ConstructorConversion, class operators::C)
+// CXX11-NEXT: 6: 2
+// CXX11-ELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], [B1.10], class operators::C)
+// CXX11-NOELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], class operators::C)
+// CXX11-NEXT: 8: operators::C([B1.7]) (CXXFunctionalCastExpr, ConstructorConversion, class operators::C)
+// CXX11-NEXT: 9: [B1.8]
+// CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, [B1.11]+1, class operators::C)
+// CXX11-NEXT: 11: [B1.5] + [B1.10] (OperatorCall)
+// CXX17-NEXT: 4: [B1.3] (CXXConstructExpr, class operators::C)
+// CXX17-NEXT: 5: operators::C([B1.4]) (CXXFunctionalCastExpr, ConstructorConversion, class operators::C)
+// CXX17-NEXT: 6: 2
+// CXX17-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9]+1, class operators::C)
+// CXX17-NEXT: 8: operators::C([B1.7]) (CXXFunctionalCastExpr, ConstructorConversion, class operators::C)
+// CXX17-NEXT: 9: [B1.5] + [B1.8] (OperatorCall)
+void testOperators() {
+ C(1) + C(2);
+}
+} // namespace operators
Index: lib/Analysis/CFG.cpp
===================================================================
--- lib/Analysis/CFG.cpp
+++ lib/Analysis/CFG.cpp
@@ -684,7 +684,7 @@
void findConstructionContexts(const ConstructionContextLayer *Layer,
Stmt *Child);
- // Scan all arguments of a call expression for a construction context.
+ // Scan all arguments of a call-like expression for a construction context.
// These sorts of call expressions don't have a common superclass,
// hence strict duck-typing.
template <typename CallLikeExpr,
@@ -694,6 +694,18 @@
std::is_same<CallLikeExpr, ObjCMessageExpr>::value>>
void findConstructionContextsForArguments(CallLikeExpr *E) {
for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
+ if (i == 0) {
+ // FIXME: This check will run for non-CallExpr variants as well,
+ // which is redundant.
+ if (const auto *OE = dyn_cast<CXXOperatorCallExpr>(E))
+ if (dyn_cast_or_null<CXXMethodDecl>(OE->getDirectCallee())) {
+ // It's an operator's this-argument that's mistaken for argument 0
+ // due to an AST inconsistency.
+ // FIXME: Actually introduce the respective construction context.
+ continue;
+ }
+ }
+
Expr *Arg = E->getArg(i);
if (Arg->getType()->getAsCXXRecordDecl() && !Arg->isGLValue())
findConstructionContexts(
Index: include/clang/Analysis/ConstructionContext.h
===================================================================
--- include/clang/Analysis/ConstructionContext.h
+++ include/clang/Analysis/ConstructionContext.h
@@ -597,9 +597,14 @@
};
class ArgumentConstructionContext : public ConstructionContext {
- const Expr *CE; // The call of which the context is an argument.
- unsigned Index; // Which argument we're constructing.
- const CXXBindTemporaryExpr *BTE; // Whether the object needs to be destroyed.
+ // The call of which the context is an argument.
+ const Expr *CE;
+ // Which argument we're constructing. Note that when numbering between
+ // arguments and parameters is inconsistent (eg., operator calls),
+ // this is the index of the argument, not of the parameter.
+ unsigned Index;
+ // Whether the object needs to be destroyed.
+ const CXXBindTemporaryExpr *BTE;
friend class ConstructionContext; // Allows to create<>() itself.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49627.156652.patch
Type: text/x-patch
Size: 4283 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180721/70f5019c/attachment.bin>
More information about the cfe-commits
mailing list