]> granicus.if.org Git - clang/commitdiff
[analyzer] NFC: Document that we support implicit argument constructors.
authorArtem Dergachev <artem.dergachev@gmail.com>
Tue, 7 Aug 2018 02:22:59 +0000 (02:22 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Tue, 7 Aug 2018 02:22:59 +0000 (02:22 +0000)
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

include/clang/Analysis/ConstructionContext.h
test/Analysis/cfg-rich-constructors.cpp
test/Analysis/temporaries.cpp

index aee67865df25043f2293548689ae2b25b1af909a..9c62bac209ae1131f6276766ea92de5ee0992961 100644 (file)
@@ -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.
 
index 88b03788da43988465d90b4714ffcbb90e54fec0..9996f5e29a38cc20b44e6df2de9f2be3bab00d82 100644 (file)
@@ -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
index e760d7ea283ade225c5415bdc8a511e27eee5630..b5a157bb8d3349947ae1b5bc1a40a66a943f3b15 100644 (file)
@@ -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
+