Skip to content

Commit

Permalink
[analyzer] NFC: Document that we support implicit argument constructors.
Browse files Browse the repository at this point in the history
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

llvm-svn: 339087
  • Loading branch information
haoNoQ committed Aug 7, 2018
1 parent 640cb00 commit 5a5b867
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
13 changes: 10 additions & 3 deletions clang/include/clang/Analysis/ConstructionContext.h
Expand Up @@ -623,9 +623,16 @@ class CXX17ElidedCopyReturnedValueConstructionContext
};

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.

Expand Down
32 changes: 32 additions & 0 deletions clang/test/Analysis/cfg-rich-constructors.cpp
Expand Up @@ -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
18 changes: 18 additions & 0 deletions clang/test/Analysis/temporaries.cpp
Expand Up @@ -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

0 comments on commit 5a5b867

Please sign in to comment.