From: Artem Dergachev Date: Tue, 7 Aug 2018 02:22:59 +0000 (+0000) Subject: [analyzer] NFC: Document that we support implicit argument constructors. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73df728949a3c9607aa81dee46af4470c35ce1b8;p=clang [analyzer] NFC: Document that we support implicit argument constructors. The change in the AST in r338135 caused us to accidentally support inlining constructors of operator implicit arguments. Previously they were hard to support because they were treated as arguments in expressions but not in declarations, but now they can be transparently treated as simple temporaries. Add tests and comments to explain how it now works. Differential Revision: https://reviews.llvm.org/D49627 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@339087 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/ConstructionContext.h b/include/clang/Analysis/ConstructionContext.h index aee67865df..9c62bac209 100644 --- a/include/clang/Analysis/ConstructionContext.h +++ b/include/clang/Analysis/ConstructionContext.h @@ -623,9 +623,16 @@ public: }; 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. diff --git a/test/Analysis/cfg-rich-constructors.cpp b/test/Analysis/cfg-rich-constructors.cpp index 88b03788da..9996f5e29a 100644 --- a/test/Analysis/cfg-rich-constructors.cpp +++ b/test/Analysis/cfg-rich-constructors.cpp @@ -963,3 +963,35 @@ void testCopyElisionWhenCopyConstructorHasExtraArguments() { 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 o +// CHECK-NEXT: 3: 1 +// CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], class operators::C) +// CHECK-NEXT: 5: operators::C([B1.4]) (CXXFunctionalCastExpr, ConstructorConversion, class operato +// CHECK-NEXT: 6: [B1.5] +// CHECK-NEXT: 7: 2 +// CXX11-ELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], [B1.11], class operators::C) +// CXX11-NOELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], class operators::C) +// CXX11-NEXT: 9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato +// CXX11-NEXT: 10: [B1.9] +// CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12]+1, class operators::C) +// CXX11-NEXT: 12: [B1.6] + [B1.11] (OperatorCall) +// CXX17-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10]+1, class operators::C) +// CXX17-NEXT: 9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato +// CXX17-NEXT: 10: [B1.6] + [B1.9] (OperatorCall) +void testOperators() { + C(1) + C(2); +} +} // namespace operators diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp index e760d7ea28..b5a157bb8d 100644 --- a/test/Analysis/temporaries.cpp +++ b/test/Analysis/temporaries.cpp @@ -986,3 +986,21 @@ void bar() { *i = 99; // no-warning } } // namespace ctor_argument + +namespace operator_implicit_argument { +struct S { + bool x; + S(bool x): x(x) {} + operator bool() const { return x; } +}; + +void foo() { + if (S(false)) { + clang_analyzer_warnIfReached(); // no-warning + } + if (S(true)) { + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + } +} +} // namespace operator_implicit_argument +