[PATCH] D48159: [clangd] Implement hover for "auto" and "decltype"

2018-06-13 Thread Marc-Andre Laperle via Phabricator via cfe-commits
malaperle created this revision.
Herald added subscribers: cfe-commits, jkorous, MaskRay, ioeric, ilya-biryukov.

This allows hovering on keywords that refer to deduced types.
This should cover most useful cases. Not covered:

- auto template parameters: Since this can be instantiated with many types,

it would not be practical to show the types.

- Structured binding: This could be done later to show multiple deduced types

in the hover.

- auto:: (part of concepts): Outside the scope of this patch.

Signed-off-by: Marc-Andre Laperle 


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D48159

Files:
  clangd/XRefs.cpp
  unittests/clangd/TestTU.cpp
  unittests/clangd/TestTU.h
  unittests/clangd/XRefsTests.cpp

Index: unittests/clangd/XRefsTests.cpp
===
--- unittests/clangd/XRefsTests.cpp
+++ unittests/clangd/XRefsTests.cpp
@@ -343,6 +343,13 @@
 
   OneTest Tests[] = {
   {
+  R"cpp(// No hover
+^int main() {
+}
+  )cpp",
+  "",
+  },
+  {
   R"cpp(// Local variable
 int main() {
   int bonjour;
@@ -637,16 +644,273 @@
   )cpp",
   "",
   },
+  {
+  R"cpp(// Simple initialization with auto
+void foo() {
+  ^auto i = 1;
+}
+  )cpp",
+  "int",
+  },
+  {
+  R"cpp(// Simple initialization with const auto
+void foo() {
+  const ^auto i = 1;
+}
+  )cpp",
+  "int",
+  },
+  {
+  R"cpp(// Simple initialization with const auto&
+void foo() {
+  const ^auto& i = 1;
+}
+  )cpp",
+  "int",
+  },
+  {
+  R"cpp(// Simple initialization with auto&
+void foo() {
+  ^auto& i = 1;
+}
+  )cpp",
+  "int",
+  },
+  {
+  R"cpp(// Auto with initializer list.
+namespace std
+{
+  template
+  class initializer_list {};
+}
+void foo() {
+  ^auto i = {1,2};
+}
+  )cpp",
+  "class std::initializer_list",
+  },
+  {
+  R"cpp(// User defined conversion to auto
+struct Bar {
+  operator ^auto() const { return 10; }
+};
+  )cpp",
+  "int",
+  },
+  {
+  R"cpp(// Simple initialization with decltype(auto)
+void foo() {
+  ^decltype(auto) i = 1;
+}
+  )cpp",
+  "int",
+  },
+  {
+  R"cpp(// Simple initialization with const decltype(auto)
+void foo() {
+  const int j = 0;
+  ^decltype(auto) i = j;
+}
+  )cpp",
+  "const int",
+  },
+  {
+  R"cpp(// Simple initialization with const& decltype(auto)
+void foo() {
+  int k = 0;
+  const int& j = k;
+  ^decltype(auto) i = j;
+}
+  )cpp",
+  "const int &",
+  },
+  {
+  R"cpp(// Simple initialization with & decltype(auto)
+void foo() {
+  int k = 0;
+  int& j = k;
+  ^decltype(auto) i = j;
+}
+  )cpp",
+  "int &",
+  },
+  {
+  R"cpp(// decltype with initializer list: nothing
+namespace std
+{
+  template
+  class initializer_list {};
+}
+void foo() {
+  ^decltype(auto) i = {1,2};
+}
+  )cpp",
+  "",
+  },
+  {
+  R"cpp(// auto function return with trailing type
+struct Bar {};
+^auto test() -> decltype(Bar()) {
+  return Bar();
+}
+  )cpp",
+  "struct Bar",
+  },
+  {
+  R"cpp(// trailing return type
+struct Bar {};
+auto test() -> ^decltype(Bar()) {
+  return Bar();
+}
+  )cpp",
+  "struct Bar",
+  },
+  {
+  R"cpp(// auto in function return
+struct Bar {};
+^auto test() {
+  return Bar();
+}
+  )cpp",
+  "struct Bar",
+  },
+  {
+  R"cpp(// auto& in function return
+struct Bar {};
+^auto& test() {
+  return Bar();
+}
+  )cpp",
+  "struct Bar",
+  },
+  {
+  R"cpp(// const auto& in function return
+struct Bar {};
+const ^auto& test() {
+  return Bar();
+}
+  )cpp",
+  "struct Bar",
+  },
+  {
+  R"cpp(// decltype(auto) in function return
+struct Bar {};
+^decltype(auto) 

[PATCH] D48027: [analyzer] Improve `CallDescription` to handle c++ method.

2018-06-13 Thread Henry Wong via Phabricator via cfe-commits
MTC added inline comments.



Comment at: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp:32
  check::PostCall> {
-  CallDescription CStrFn;
+  const llvm::SmallVector CStrFnFamily = {
+{"std::basic_string::c_str"}, {"std::basic_string::c_str"},

NoQ wrote:
> xazax.hun wrote:
> > I am not sure if this is the right solution in case of this check. We 
> > should track `c_str` calls regardless of what the template parameter is, so 
> > supporting any instantiation of `basic_string` is desired. This might not 
> > be the case, however, for other checks. 
> > 
> > If we think it is more likely we do not care about the template arguments, 
> > maybe a separate API could be used, where we pass the qualified name of the 
> > class separately without the template arguments.
> > Alternatively, we could use matches name so the users could use regexps.
> > 
> > At this point I also wonder what isCalled API gives us compared to 
> > matchers? Maybe it is more convenient to use than calling a `match`. Also, 
> > isCalled API has an IdentifierInfo cached which could be used for 
> > relatively efficient checks.
> > 
> > @NoQ what do you think?
> > 
> > 
> I agree that it's better to match the chain of classes and namespaces (in as 
> much detail as the user cares to provide) and discard template parameters.
> 
> For example, i wish that a `CallDescription` that's defined as `{"std", 
> "basic_string", "c_str"}` would be able to match both `std::string::c_str()` 
> and `std::__1::string::c_str()`.
Yea, checker writers may can't provide all the template arguments, and it's not 
convenient to use!

I will try to give a better solution!



Comment at: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp:65
   auto *TypeDecl = TypedR->getValueType()->getAsCXXRecordDecl();
   if (TypeDecl->getName() != "basic_string")
 return;

xazax.hun wrote:
> If we check for fully qualified names, this check might be redundant.
Right, thanks!



Comment at: lib/StaticAnalyzer/Core/CallEvent.cpp:273
+  auto Matches =
+  match(namedDecl(hasName(CD.FuncName)).bind("match_qualified_name"), *ND,
+LCtx->getAnalysisDeclContext()->getASTContext());

xazax.hun wrote:
> Doesn't match also traverse the subtree of the AST? We only need to check if 
> that particular node matches the qualified name. I wonder if we could, during 
> the traversal, find another node that is a match unintentionally.
Yea, this maybe a problem, I will test whether this is going to happen and give 
a fine-grained match. Thanks!



Repository:
  rC Clang

https://reviews.llvm.org/D48027



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47687: [Sema] Missing -Wlogical-op-parentheses warnings in macros (PR18971)

2018-06-13 Thread Xing via Phabricator via cfe-commits
Higuoxing updated this revision to Diff 151290.
Higuoxing added a comment.

Ping, well, I think I understand `@dexonsmith`'s idea.

`Actionable` macro argument is just like something like this

  #define foo(x) ( (void)(x) )

when we using it by

  foo(a && b || c);

we could add parentheses for it by

  foo((a && b) || c);

However, the following example is `not actionable`

  #define foo(op0, op1, x, y, z) ( (void)(x op0 y op1 z) )

when we using it by

  foo(&&, ||, x, y, z);

because, we also probably use it by

  foo(+, *, x, y, z)

So, we cannot add parentheses for it carelessly...

My opinion is that, to judge if an `expr` is actionable is to test if the op 
and both LHS and RHS are from same context or same argument position from 
macro... But I cannot find such API for indicating a `expression` expanded 
position exactly. There are API like: `isMacroArgExpansion` and 
`isMacroBodyExpansion` which is determined by row string positions...

So, what I can do now for this is that using API `isMacroArgExpansion()` to let 
it check the parentheses defined or expanded totally inside a macro like

  #define foo(x, y, z) ( x && y || z )

The shortage is that we cannot check parentheses for this case:

  foo(x && y || z); 

because the operator is expanded from macro arguments.

Thanks


https://reviews.llvm.org/D47687

Files:
  lib/Sema/SemaExpr.cpp
  test/Sema/logical-op-parentheses-in-macros.c

Index: test/Sema/logical-op-parentheses-in-macros.c
===
--- test/Sema/logical-op-parentheses-in-macros.c
+++ test/Sema/logical-op-parentheses-in-macros.c
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify=logical_op_parentheses_check %s
+
+// operator of this case is expanded from macro function argument
+#define macro_op_parentheses_check(x) ( \
+  ( (void)(x) ) \
+)
+
+// operator of this case is expanded from macro function body
+#define macro_op_parentheses_check_ops_args(op0, op1, x, y, z) ( \
+  ( (void) (x op0 y op1 z ) ) \
+)
+
+// operator of this case is expanded from macro function body
+#define macro_op_parentheses_check_ops_args2(op0, op1, op2, w, x, y, z) ( \
+  ( (void) (w op0 x op1 y op2 z) ) \
+)
+
+// operator of this case is expanded from marco body
+#define macro_op_parentheses_check_ops_body(x, y, z) ( \
+  ( (void) (x && y || z) ) \
+)
+
+void logical_op_from_macro_arguments(unsigned i) {
+  macro_op_parentheses_check(i || i && i); // no warning.
+  macro_op_parentheses_check(i || i && "I love LLVM"); // no warning.
+  macro_op_parentheses_check("I love LLVM" && i || i); // no warning.
+
+  macro_op_parentheses_check(i || i && "I love LLVM" || i); // no warning.
+  macro_op_parentheses_check(i || "I love LLVM" && i || i); // no warning.
+  macro_op_parentheses_check(i && i || 0); // no warning.
+  macro_op_parentheses_check(0 || i && i); // no warning.
+}
+
+void logical_op_from_macro_arguments2(unsigned i) {
+  macro_op_parentheses_check_ops_args(||, &&, i, i, i);  // no warning.
+  macro_op_parentheses_check_ops_args(||, &&, i, i, "I love LLVM");  // no warning.
+  macro_op_parentheses_check_ops_args(&&, ||, "I love LLVM", i, i);  // no warning.
+
+  macro_op_parentheses_check_ops_args2(||, &&, ||, i, i, "I love LLVM", i); // no warning.
+  macro_op_parentheses_check_ops_args2(||, &&, ||, i, "I love LLVM", i, i); // no warning.
+
+  macro_op_parentheses_check_ops_args(&&, ||, i, i, 0); // no warning.
+  macro_op_parentheses_check_ops_args(||, &&, 0, i, i); // no warning.
+}
+
+void logical_op_from_macro_body(unsigned i) {
+  macro_op_parentheses_check_ops_body(i, i, i); // logical_op_parentheses_check-warning {{'&&' within '||'}} \
+// logical_op_parentheses_check-note {{place parentheses around the '&&' expression to silence this warning}}
+}
\ No newline at end of file
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -12172,7 +12172,7 @@
 EmitDiagnosticForLogicalAndInLogicalOr(Sema , SourceLocation OpLoc,
BinaryOperator *Bop) {
   assert(Bop->getOpcode() == BO_LAnd);
-  Self.Diag(Bop->getOperatorLoc(), diag::warn_logical_and_in_logical_or)
+  Self.Diag(Bop->getOperatorLoc(), diag::warn_logical_and_in_logical_or) 
   << Bop->getSourceRange() << OpLoc;
   SuggestParentheses(Self, Bop->getOperatorLoc(),
 Self.PDiag(diag::note_precedence_silence)
@@ -12205,6 +12205,7 @@
   if (EvaluatesAsFalse(S, RHSExpr))
 return;
   // If it's "1 && a || b" don't warn since the precedence doesn't matter.
+  // And 'assert("some message" && a || b)' don't warn as well.
   if (!EvaluatesAsTrue(S, Bop->getLHS()))
 return EmitDiagnosticForLogicalAndInLogicalOr(S, OpLoc, Bop);
 } else if (Bop->getOpcode() == BO_LOr) {
@@ -12227,6 +12228,7 @@
   if (EvaluatesAsFalse(S, LHSExpr))
   

[PATCH] D47405: [analyzer] Re-enable C++17-specific return value constructors.

2018-06-13 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC334684: [analyzer] Re-enable C++17-specific RVO construction 
contexts. (authored by dergachev, committed by ).
Herald added a subscriber: mikhail.ramalho.

Repository:
  rC Clang

https://reviews.llvm.org/D47405

Files:
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/cxx17-mandatory-elision.cpp

Index: test/Analysis/cxx17-mandatory-elision.cpp
===
--- test/Analysis/cxx17-mandatory-elision.cpp
+++ test/Analysis/cxx17-mandatory-elision.cpp
@@ -150,9 +150,8 @@
   ClassWithoutDestructor c = make3(v);
 
 #if __cplusplus >= 201703L
-  // FIXME: Both should be TRUE.
   clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
-  clang_analyzer_eval(v.buf[0] == ); // expected-warning{{FALSE}}
+  clang_analyzer_eval(v.buf[0] == ); // expected-warning{{TRUE}}
 #else
   clang_analyzer_eval(v.len == 5); // expected-warning{{TRUE}}
   clang_analyzer_eval(v.buf[0] != v.buf[1]); // expected-warning{{TRUE}}
@@ -183,6 +182,13 @@
   AddressVector v;
   {
 ClassWithDestructor c = ClassWithDestructor(v);
+// Check if the last destructor is an automatic destructor.
+// A temporary destructor would have fired by now.
+#if __cplusplus >= 201703L
+clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
+#else
+clang_analyzer_eval(v.len == 3); // expected-warning{{TRUE}}
+#endif
   }
 #if __cplusplus >= 201703L
   // 0. Construct the variable.
@@ -210,6 +216,13 @@
   AddressVector v;
   {
 TestCtorInitializer t(v);
+// Check if the last destructor is an automatic destructor.
+// A temporary destructor would have fired by now.
+#if __cplusplus >= 201703L
+clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
+#else
+clang_analyzer_eval(v.len == 3); // expected-warning{{TRUE}}
+#endif
   }
 #if __cplusplus >= 201703L
   // 0. Construct the member variable.
@@ -227,4 +240,53 @@
 #endif
 }
 
+
+ClassWithDestructor make1(AddressVector ) {
+  return ClassWithDestructor(v);
+}
+ClassWithDestructor make2(AddressVector ) {
+  return make1(v);
+}
+ClassWithDestructor make3(AddressVector ) {
+  return make2(v);
+}
+
+void testMultipleReturnsWithDestructors() {
+  AddressVector v;
+  {
+ClassWithDestructor c = make3(v);
+// Check if the last destructor is an automatic destructor.
+// A temporary destructor would have fired by now.
+#if __cplusplus >= 201703L
+clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
+#else
+clang_analyzer_eval(v.len == 9); // expected-warning{{TRUE}}
+#endif
+  }
+
+#if __cplusplus >= 201703L
+  // 0. Construct the variable. Yes, constructor in make1() constructs
+  //the variable 'c'.
+  // 1. Destroy the variable.
+  clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
+#else
+  // 0. Construct the temporary in make1().
+  // 1. Construct the temporary in make2().
+  // 2. Destroy the temporary in make1().
+  // 3. Construct the temporary in make3().
+  // 4. Destroy the temporary in make2().
+  // 5. Construct the temporary here.
+  // 6. Destroy the temporary in make3().
+  // 7. Construct the variable.
+  // 8. Destroy the temporary here.
+  // 9. Destroy the variable.
+  clang_analyzer_eval(v.len == 10); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[1] == v.buf[4]); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[3] == v.buf[6]); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[5] == v.buf[8]); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[7] == v.buf[9]); // expected-warning{{TRUE}}
+#endif
+}
 } // namespace address_vector_tests
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -180,7 +180,8 @@
   }
   break;
 }
-case ConstructionContext::SimpleReturnedValueKind: {
+case ConstructionContext::SimpleReturnedValueKind:
+case ConstructionContext::CXX17ElidedCopyReturnedValueKind: {
   // The temporary is to be managed by the parent stack frame.
   // So build it in the parent stack frame if we're not in the
   // top frame of the analysis.
@@ -193,16 +194,10 @@
   // call in the parent stack frame. This is equivalent to not being
   // able to find construction context at all.
   break;
-} else if (!isa(
-   RTC->getConstructionContext())) {
-  // FIXME: The return value is constructed directly into a
-  // non-temporary due to C++17 mandatory copy elision. This is not
-  // implemented yet.
-  assert(getContext().getLangOpts().CPlusPlus17);
-  break;
 }
-CC = 

r334684 - [analyzer] Re-enable C++17-specific RVO construction contexts.

2018-06-13 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Wed Jun 13 18:59:35 2018
New Revision: 334684

URL: http://llvm.org/viewvc/llvm-project?rev=334684=rev
Log:
[analyzer] Re-enable C++17-specific RVO construction contexts.

Not contexts themselves, but rather support for them in the analyzer.

Such construction contexts appear when C++17 mandatory copy elision occurs
while returning an object from a function, and presence of a destructor causes
a CXXBindTemporaryExpr to appear in the AST.

Additionally, such construction contexts may be chained, because a return-value
construction context doesn't really explain where the object is being returned
into, but only points to the parent stack frame, where the object may be
consumed by literally anything including another return statement. This
behavior is now modeled correctly by the analyzer as long as the object is not
returned beyond the boundaries of the analysis.

Differential Revision: https://reviews.llvm.org/D47405

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=334684=334683=334684=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Wed Jun 13 18:59:35 2018
@@ -180,7 +180,8 @@ std::pair ExprEng
   }
   break;
 }
-case ConstructionContext::SimpleReturnedValueKind: {
+case ConstructionContext::SimpleReturnedValueKind:
+case ConstructionContext::CXX17ElidedCopyReturnedValueKind: {
   // The temporary is to be managed by the parent stack frame.
   // So build it in the parent stack frame if we're not in the
   // top frame of the analysis.
@@ -193,16 +194,10 @@ std::pair ExprEng
   // call in the parent stack frame. This is equivalent to not being
   // able to find construction context at all.
   break;
-} else if (!isa(
-   RTC->getConstructionContext())) {
-  // FIXME: The return value is constructed directly into a
-  // non-temporary due to C++17 mandatory copy elision. This is not
-  // implemented yet.
-  assert(getContext().getLangOpts().CPlusPlus17);
-  break;
 }
-CC = RTC->getConstructionContext();
-LCtx = CallerLCtx;
+return prepareForObjectConstruction(
+cast(SFC->getCallSite()), State, CallerLCtx,
+RTC->getConstructionContext(), CallOpts);
   } else {
 // We are on the top frame of the analysis.
 // TODO: What exactly happens when we are? Does the temporary object
@@ -212,9 +207,7 @@ std::pair ExprEng
 SVal V = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
 return std::make_pair(State, V);
   }
-
-  // Continue as if we have a temporary with a different location context.
-  // FALLTHROUGH.
+  llvm_unreachable("Unhandled return value construction context!");
 }
 case ConstructionContext::TemporaryObjectKind: {
   const auto *TCC = cast(CC);
@@ -261,9 +254,6 @@ std::pair ExprEng
   CallOpts.IsTemporaryCtorOrDtor = true;
   return std::make_pair(State, V);
 }
-case ConstructionContext::CXX17ElidedCopyReturnedValueKind:
-  // Not implemented yet.
-  break;
 }
   }
   // If we couldn't find an existing region to construct into, assume we're

Modified: cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp?rev=334684=334683=334684=diff
==
--- cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp (original)
+++ cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp Wed Jun 13 18:59:35 2018
@@ -150,9 +150,8 @@ void testMultipleReturns() {
   ClassWithoutDestructor c = make3(v);
 
 #if __cplusplus >= 201703L
-  // FIXME: Both should be TRUE.
   clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
-  clang_analyzer_eval(v.buf[0] == ); // expected-warning{{FALSE}}
+  clang_analyzer_eval(v.buf[0] == ); // expected-warning{{TRUE}}
 #else
   clang_analyzer_eval(v.len == 5); // expected-warning{{TRUE}}
   clang_analyzer_eval(v.buf[0] != v.buf[1]); // expected-warning{{TRUE}}
@@ -183,6 +182,13 @@ void testVariable() {
   AddressVector v;
   {
 ClassWithDestructor c = ClassWithDestructor(v);
+// Check if the last destructor is an automatic destructor.
+// A temporary destructor would have fired by now.
+#if __cplusplus >= 201703L
+clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
+#else
+clang_analyzer_eval(v.len == 3); // expected-warning{{TRUE}}
+#endif
   }
 #if __cplusplus >= 201703L
   // 0. Construct the variable.
@@ 

[PATCH] D47351: [analyzer] Re-enable C++17-specific variable and member variable construction contexts.

2018-06-13 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC334683: [analyzer] Re-enable C++17-specific variable and 
member construction contexts. (authored by dergachev, committed by ).
Herald added a subscriber: mikhail.ramalho.

Repository:
  rC Clang

https://reviews.llvm.org/D47351

Files:
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/cxx17-mandatory-elision.cpp

Index: test/Analysis/cxx17-mandatory-elision.cpp
===
--- test/Analysis/cxx17-mandatory-elision.cpp
+++ test/Analysis/cxx17-mandatory-elision.cpp
@@ -49,9 +49,64 @@
   }
 };
 
+
+struct A {
+  int x;
+  A(): x(0) {}
+  ~A() {}
+};
+
+struct B {
+  A a;
+  B() : a(A()) {}
+};
+
+void foo() {
+  B b;
+  clang_analyzer_eval(b.a.x == 0); // expected-warning{{TRUE}}
+}
+
 } // namespace ctor_initializer
 
 
+namespace elision_on_ternary_op_branches {
+class C1 {
+  int x;
+public:
+  C1(int x): x(x) {}
+  int getX() const { return x; }
+  ~C1();
+};
+
+class C2 {
+  int x;
+  int y;
+public:
+  C2(int x, int y): x(x), y(y) {}
+  int getX() const { return x; }
+  int getY() const { return y; }
+  ~C2();
+};
+
+void foo(int coin) {
+  C1 c1 = coin ? C1(1) : C1(2);
+  if (coin) {
+clang_analyzer_eval(c1.getX() == 1); // expected-warning{{TRUE}}
+  } else {
+clang_analyzer_eval(c1.getX() == 2); // expected-warning{{TRUE}}
+  }
+  C2 c2 = coin ? C2(3, 4) : C2(5, 6);
+  if (coin) {
+clang_analyzer_eval(c2.getX() == 3); // expected-warning{{TRUE}}
+clang_analyzer_eval(c2.getY() == 4); // expected-warning{{TRUE}}
+  } else {
+clang_analyzer_eval(c2.getX() == 5); // expected-warning{{TRUE}}
+clang_analyzer_eval(c2.getY() == 6); // expected-warning{{TRUE}}
+  }
+}
+} // namespace elision_on_ternary_op_branches
+
+
 namespace address_vector_tests {
 
 template  struct AddressVector {
@@ -108,4 +163,68 @@
 #endif
 }
 
+class ClassWithDestructor {
+  AddressVector 
+
+public:
+  ClassWithDestructor(AddressVector ) : v(v) {
+v.push(this);
+  }
+
+  ClassWithDestructor(ClassWithDestructor &) : v(c.v) { v.push(this); }
+  ClassWithDestructor(const ClassWithDestructor ) : v(c.v) {
+v.push(this);
+  }
+
+  ~ClassWithDestructor() { v.push(this); }
+};
+
+void testVariable() {
+  AddressVector v;
+  {
+ClassWithDestructor c = ClassWithDestructor(v);
+  }
+#if __cplusplus >= 201703L
+  // 0. Construct the variable.
+  // 1. Destroy the variable.
+  clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
+#else
+  // 0. Construct the temporary.
+  // 1. Construct the variable.
+  // 2. Destroy the temporary.
+  // 3. Destroy the variable.
+  clang_analyzer_eval(v.len == 4); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[1] == v.buf[3]); // expected-warning{{TRUE}}
+#endif
+}
+
+struct TestCtorInitializer {
+  ClassWithDestructor c;
+  TestCtorInitializer(AddressVector )
+: c(ClassWithDestructor(v)) {}
+};
+
+void testCtorInitializer() {
+  AddressVector v;
+  {
+TestCtorInitializer t(v);
+  }
+#if __cplusplus >= 201703L
+  // 0. Construct the member variable.
+  // 1. Destroy the member variable.
+  clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
+#else
+  // 0. Construct the temporary.
+  // 1. Construct the member variable.
+  // 2. Destroy the temporary.
+  // 3. Destroy the member variable.
+  clang_analyzer_eval(v.len == 4); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[1] == v.buf[3]); // expected-warning{{TRUE}}
+#endif
+}
+
 } // namespace address_vector_tests
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -119,8 +119,9 @@
   // current construction context.
   if (CC) {
 switch (CC->getKind()) {
+case ConstructionContext::CXX17ElidedCopyVariableKind:
 case ConstructionContext::SimpleVariableKind: {
-  const auto *DSCC = cast(CC);
+  const auto *DSCC = cast(CC);
   const auto *DS = DSCC->getDeclStmt();
   const auto *Var = cast(DS->getSingleDecl());
   SVal LValue = State->getLValue(Var, LCtx);
@@ -131,6 +132,7 @@
   addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, LValue);
   return std::make_pair(State, LValue);
 }
+case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
 case ConstructionContext::SimpleConstructorInitializerKind: {
   const auto *ICC = cast(CC);
   const auto *Init = ICC->getCXXCtorInitializer();
@@ -259,9 +261,7 @@
   CallOpts.IsTemporaryCtorOrDtor = true;
   return std::make_pair(State, V);
 }
-   

r334683 - [analyzer] Re-enable C++17-specific variable and member construction contexts.

2018-06-13 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Wed Jun 13 18:54:21 2018
New Revision: 334683

URL: http://llvm.org/viewvc/llvm-project?rev=334683=rev
Log:
[analyzer] Re-enable C++17-specific variable and member construction contexts.

Not contexts themselves, but rather support for them in the analyzer.

Such construction contexts appear when C++17 mandatory copy elision occurs
during initialization, and presence of a destructor causes a
CXXBindTemporaryExpr to appear in the AST.

Similar C++17-specific constructors for return values are still to be supported.

Differential Revision: https://reviews.llvm.org/D47351

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=334683=334682=334683=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Wed Jun 13 18:54:21 2018
@@ -119,8 +119,9 @@ std::pair ExprEng
   // current construction context.
   if (CC) {
 switch (CC->getKind()) {
+case ConstructionContext::CXX17ElidedCopyVariableKind:
 case ConstructionContext::SimpleVariableKind: {
-  const auto *DSCC = cast(CC);
+  const auto *DSCC = cast(CC);
   const auto *DS = DSCC->getDeclStmt();
   const auto *Var = cast(DS->getSingleDecl());
   SVal LValue = State->getLValue(Var, LCtx);
@@ -131,6 +132,7 @@ std::pair ExprEng
   addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, LValue);
   return std::make_pair(State, LValue);
 }
+case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
 case ConstructionContext::SimpleConstructorInitializerKind: {
   const auto *ICC = cast(CC);
   const auto *Init = ICC->getCXXCtorInitializer();
@@ -259,9 +261,7 @@ std::pair ExprEng
   CallOpts.IsTemporaryCtorOrDtor = true;
   return std::make_pair(State, V);
 }
-case ConstructionContext::CXX17ElidedCopyVariableKind:
 case ConstructionContext::CXX17ElidedCopyReturnedValueKind:
-case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
   // Not implemented yet.
   break;
 }

Modified: cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp?rev=334683=334682=334683=diff
==
--- cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp (original)
+++ cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp Wed Jun 13 18:54:21 2018
@@ -49,9 +49,64 @@ public:
   }
 };
 
+
+struct A {
+  int x;
+  A(): x(0) {}
+  ~A() {}
+};
+
+struct B {
+  A a;
+  B() : a(A()) {}
+};
+
+void foo() {
+  B b;
+  clang_analyzer_eval(b.a.x == 0); // expected-warning{{TRUE}}
+}
+
 } // namespace ctor_initializer
 
 
+namespace elision_on_ternary_op_branches {
+class C1 {
+  int x;
+public:
+  C1(int x): x(x) {}
+  int getX() const { return x; }
+  ~C1();
+};
+
+class C2 {
+  int x;
+  int y;
+public:
+  C2(int x, int y): x(x), y(y) {}
+  int getX() const { return x; }
+  int getY() const { return y; }
+  ~C2();
+};
+
+void foo(int coin) {
+  C1 c1 = coin ? C1(1) : C1(2);
+  if (coin) {
+clang_analyzer_eval(c1.getX() == 1); // expected-warning{{TRUE}}
+  } else {
+clang_analyzer_eval(c1.getX() == 2); // expected-warning{{TRUE}}
+  }
+  C2 c2 = coin ? C2(3, 4) : C2(5, 6);
+  if (coin) {
+clang_analyzer_eval(c2.getX() == 3); // expected-warning{{TRUE}}
+clang_analyzer_eval(c2.getY() == 4); // expected-warning{{TRUE}}
+  } else {
+clang_analyzer_eval(c2.getX() == 5); // expected-warning{{TRUE}}
+clang_analyzer_eval(c2.getY() == 6); // expected-warning{{TRUE}}
+  }
+}
+} // namespace elision_on_ternary_op_branches
+
+
 namespace address_vector_tests {
 
 template  struct AddressVector {
@@ -108,4 +163,68 @@ void testMultipleReturns() {
 #endif
 }
 
+class ClassWithDestructor {
+  AddressVector 
+
+public:
+  ClassWithDestructor(AddressVector ) : v(v) {
+v.push(this);
+  }
+
+  ClassWithDestructor(ClassWithDestructor &) : v(c.v) { v.push(this); }
+  ClassWithDestructor(const ClassWithDestructor ) : v(c.v) {
+v.push(this);
+  }
+
+  ~ClassWithDestructor() { v.push(this); }
+};
+
+void testVariable() {
+  AddressVector v;
+  {
+ClassWithDestructor c = ClassWithDestructor(v);
+  }
+#if __cplusplus >= 201703L
+  // 0. Construct the variable.
+  // 1. Destroy the variable.
+  clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
+#else
+  // 0. Construct the temporary.
+  // 1. Construct the variable.
+  // 2. Destroy the temporary.
+  // 3. Destroy the variable.
+  clang_analyzer_eval(v.len == 4); // 

[PATCH] D47393: [clang-format] Disable AlwaysBreakBeforeMultilineStrings in Google style for Objective-C 

2018-06-13 Thread Stephane Moore via Phabricator via cfe-commits
stephanemoore added a comment.

Are additional approvals needed to land this? I pinged jolesiak earlier this 
week asking if he had any comments but have not heard back yet.

(also, once necessary approvals have been granted can I request help from 
someone to land it for me? )


Repository:
  rC Clang

https://reviews.llvm.org/D47393



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r334682 - [analyzer] Track class member initializer constructors path-sensitively.

2018-06-13 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Wed Jun 13 18:40:49 2018
New Revision: 334682

URL: http://llvm.org/viewvc/llvm-project?rev=334682=rev
Log:
[analyzer] Track class member initializer constructors path-sensitively.

The reasoning behind this change is similar to the previous commit, r334681.
Because members are already in scope when construction occurs, we are not
suffering from liveness problems, but we still want to figure out if the object
was constructed with construction context, because in this case we'll be able
to avoid trivial copy, which we don't always model perfectly. It'd also have
more importance when copy elision is implemented.

This also gets rid of the old CFG look-behind mechanism.

Differential Revision: https://reviews.llvm.org/D47350

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=334682=334681=334682=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Wed 
Jun 13 18:40:49 2018
@@ -762,20 +762,23 @@ private:
   /// made within the constructor alive until its declaration actually
   /// goes into scope.
   static ProgramStateRef addObjectUnderConstruction(
-  ProgramStateRef State, const Stmt *S,
+  ProgramStateRef State,
+  llvm::PointerUnion P,
   const LocationContext *LC, SVal V);
 
   /// Mark the object sa fully constructed, cleaning up the state trait
   /// that tracks objects under construction.
-  static ProgramStateRef finishObjectConstruction(ProgramStateRef State,
-  const Stmt *S,
-  const LocationContext *LC);
+  static ProgramStateRef finishObjectConstruction(
+  ProgramStateRef State,
+  llvm::PointerUnion P,
+  const LocationContext *LC);
 
   /// If the given statement corresponds to an object under construction,
   /// being part of its construciton context, retrieve that object's location.
-  static Optional getObjectUnderConstruction(ProgramStateRef State,
-   const Stmt *S,
-   const LocationContext *LC);
+  static Optional getObjectUnderConstruction(
+  ProgramStateRef State,
+  llvm::PointerUnion P,
+  const LocationContext *LC);
 
   /// Check if all objects under construction have been fully constructed
   /// for the given context range (including FromLC, not including ToLC).

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=334682=334681=334682=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed Jun 13 18:40:49 2018
@@ -109,7 +109,75 @@ STATISTIC(NumTimesRetriedWithoutInlining
 // to the object's location, so that on every such statement the location
 // could have been retrieved.
 
-typedef std::pair ConstructedObjectKey;
+/// ConstructedObjectKey is used for being able to find the path-sensitive
+/// memory region of a freshly constructed object while modeling the AST node
+/// that syntactically represents the object that is being constructed.
+/// Semantics of such nodes may sometimes require access to the region that's
+/// not otherwise present in the program state, or to the very fact that
+/// the construction context was present and contained references to these
+/// AST nodes.
+class ConstructedObjectKey {
+  typedef std::pair<
+  llvm::PointerUnion,
+  const LocationContext *> ConstructedObjectKeyImpl;
+
+  ConstructedObjectKeyImpl Impl;
+
+  const void *getAnyASTNodePtr() const {
+if (const Stmt *S = getStmt())
+  return S;
+else
+  return getCXXCtorInitializer();
+  }
+
+public:
+  ConstructedObjectKey(
+  llvm::PointerUnion P,
+  const LocationContext *LC)
+  : Impl(P, LC) {
+// This is the full list of statements that require additional actions when
+// encountered. This list may be expanded when new actions are implemented.
+assert(getCXXCtorInitializer() || isa(getStmt()) ||
+   isa(getStmt()) || isa(getStmt()) 
||
+   isa(getStmt()));
+  }
+
+  const Stmt *getStmt() const {
+return Impl.first.dyn_cast();
+  }
+
+  const CXXCtorInitializer *getCXXCtorInitializer() const {
+return Impl.first.dyn_cast();
+  }
+
+  

[PATCH] D47350: [analyzer] Track class member initializer constructors path-sensitively within their construction context.

2018-06-13 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC334682: [analyzer] Track class member initializer 
constructors path-sensitively. (authored by dergachev, committed by ).
Herald added a subscriber: mikhail.ramalho.

Repository:
  rC Clang

https://reviews.llvm.org/D47350

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/cxx17-mandatory-elision.cpp

Index: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -762,20 +762,23 @@
   /// made within the constructor alive until its declaration actually
   /// goes into scope.
   static ProgramStateRef addObjectUnderConstruction(
-  ProgramStateRef State, const Stmt *S,
+  ProgramStateRef State,
+  llvm::PointerUnion P,
   const LocationContext *LC, SVal V);
 
   /// Mark the object sa fully constructed, cleaning up the state trait
   /// that tracks objects under construction.
-  static ProgramStateRef finishObjectConstruction(ProgramStateRef State,
-  const Stmt *S,
-  const LocationContext *LC);
+  static ProgramStateRef finishObjectConstruction(
+  ProgramStateRef State,
+  llvm::PointerUnion P,
+  const LocationContext *LC);
 
   /// If the given statement corresponds to an object under construction,
   /// being part of its construciton context, retrieve that object's location.
-  static Optional getObjectUnderConstruction(ProgramStateRef State,
-   const Stmt *S,
-   const LocationContext *LC);
+  static Optional getObjectUnderConstruction(
+  ProgramStateRef State,
+  llvm::PointerUnion P,
+  const LocationContext *LC);
 
   /// Check if all objects under construction have been fully constructed
   /// for the given context range (including FromLC, not including ToLC).
Index: test/Analysis/cxx17-mandatory-elision.cpp
===
--- test/Analysis/cxx17-mandatory-elision.cpp
+++ test/Analysis/cxx17-mandatory-elision.cpp
@@ -21,6 +21,37 @@
 } // namespace variable_functional_cast_crash
 
 
+namespace ctor_initializer {
+
+struct S {
+  int x, y, z;
+};
+
+struct T {
+  S s;
+  int w;
+  T(int w): s(), w(w) {}
+};
+
+class C {
+  T t;
+public:
+  C() : t(T(4)) {
+S s = {1, 2, 3};
+t.s = s;
+// FIXME: Should be TRUE in C++11 as well.
+clang_analyzer_eval(t.w == 4);
+#if __cplusplus >= 201703L
+// expected-warning@-2{{TRUE}}
+#else
+// expected-warning@-4{{UNKNOWN}}
+#endif
+  }
+};
+
+} // namespace ctor_initializer
+
+
 namespace address_vector_tests {
 
 template  struct AddressVector {
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -109,7 +109,75 @@
 // to the object's location, so that on every such statement the location
 // could have been retrieved.
 
-typedef std::pair ConstructedObjectKey;
+/// ConstructedObjectKey is used for being able to find the path-sensitive
+/// memory region of a freshly constructed object while modeling the AST node
+/// that syntactically represents the object that is being constructed.
+/// Semantics of such nodes may sometimes require access to the region that's
+/// not otherwise present in the program state, or to the very fact that
+/// the construction context was present and contained references to these
+/// AST nodes.
+class ConstructedObjectKey {
+  typedef std::pair<
+  llvm::PointerUnion,
+  const LocationContext *> ConstructedObjectKeyImpl;
+
+  ConstructedObjectKeyImpl Impl;
+
+  const void *getAnyASTNodePtr() const {
+if (const Stmt *S = getStmt())
+  return S;
+else
+  return getCXXCtorInitializer();
+  }
+
+public:
+  ConstructedObjectKey(
+  llvm::PointerUnion P,
+  const LocationContext *LC)
+  : Impl(P, LC) {
+// This is the full list of statements that require additional actions when
+// encountered. This list may be expanded when new actions are implemented.
+assert(getCXXCtorInitializer() || isa(getStmt()) ||
+   isa(getStmt()) || isa(getStmt()) ||
+   isa(getStmt()));
+  }
+
+  const Stmt *getStmt() const {
+return Impl.first.dyn_cast();
+  }
+
+  const CXXCtorInitializer *getCXXCtorInitializer() const {
+return Impl.first.dyn_cast();
+  }
+
+  const LocationContext *getLocationContext() const {
+return Impl.second;
+  }
+
+  void print(llvm::raw_ostream , PrinterHelper *Helper, PrintingPolicy ) {

r334681 - [analyzer] pr37270: Track constructor target region, even if just a variable.

2018-06-13 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Wed Jun 13 18:32:46 2018
New Revision: 334681

URL: http://llvm.org/viewvc/llvm-project?rev=334681=rev
Log:
[analyzer] pr37270: Track constructor target region, even if just a variable.

The very idea of construction context implies that first the object is
constructed, and then later, in a separate moment of time, the constructed
object goes into scope, i.e. becomes "live".

Most construction contexts require path-sensitive tracking of the constructed
object region in order to compute the outer expressions accordingly before
the object becomes live.

Semantics of simple variable construction contexts don't immediately require
that such tracking happens in path-sensitive manner, but shortcomings of the
analyzer force us to track it path-sensitively as well. Namely, whether
construction context was available at all during construction is a
path-sensitive information. Additionally, path-sensitive tracking takes care of
our liveness problems that kick in as the temporal gap between construction and
going-into-scope becomes larger (eg., due to copy elision).

Differential Revision: https://reviews.llvm.org/D47305

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=334681=334680=334681=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Wed Jun 13 18:32:46 2018
@@ -590,24 +590,12 @@ void ExprEngine::VisitDeclStmt(const Dec
   SVal InitVal = state->getSVal(InitEx, LC);
 
   assert(DS->isSingleDecl());
-  if (auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) {
-assert(InitEx->IgnoreImplicit() == CtorExpr);
-(void)CtorExpr;
+  if (getObjectUnderConstruction(state, DS, LC)) {
+state = finishObjectConstruction(state, DS, LC);
 // We constructed the object directly in the variable.
 // No need to bind anything.
 B.generateNode(DS, UpdatedN, state);
   } else {
-// We bound the temp obj region to the CXXConstructExpr. Now recover
-// the lazy compound value when the variable is not a reference.
-if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
-!VD->getType()->isReferenceType()) {
-  if (Optional M =
-  InitVal.getAs()) {
-InitVal = state->getSVal(M->getRegion());
-assert(InitVal.getAs());
-  }
-}
-
 // Recover some path-sensitivity if a scalar value evaluated to
 // UnknownVal.
 if (InitVal.isUnknown()) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=334681=334680=334681=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Wed Jun 13 18:32:46 2018
@@ -125,9 +125,11 @@ std::pair ExprEng
   const auto *Var = cast(DS->getSingleDecl());
   SVal LValue = State->getLValue(Var, LCtx);
   QualType Ty = Var->getType();
-  return std::make_pair(
-  State,
-  makeZeroElementRegion(State, LValue, Ty, 
CallOpts.IsArrayCtorOrDtor));
+  LValue =
+  makeZeroElementRegion(State, LValue, Ty, CallOpts.IsArrayCtorOrDtor);
+  State =
+  addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, LValue);
+  return std::make_pair(State, LValue);
 }
 case ConstructionContext::SimpleConstructorInitializerKind: {
   const auto *ICC = cast(CC);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=334681=334680=334681=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Wed Jun 13 
18:32:46 2018
@@ -193,23 +193,6 @@ static bool wasDifferentDeclUsedForInlin
   return RuntimeCallee->getCanonicalDecl() != StaticDecl->getCanonicalDecl();
 }
 
-/// Returns true if the CXXConstructExpr \p E was intended to construct a
-/// prvalue for the region in \p V.
-///
-/// Note that we can't just test for rvalue vs. glvalue because
-/// CXXConstructExprs embedded in DeclStmts and initializers are considered
-/// rvalues by the AST, and the analyzer would like to treat them as lvalues.
-static 

[PATCH] D47305: [analyzer] pr37270: Fix binding constructed object to DeclStmt when ConstructionContext is already lost.

2018-06-13 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL334681: [analyzer] pr37270: Track constructor target region, 
even if just a variable. (authored by dergachev, committed by ).
Herald added subscribers: llvm-commits, mikhail.ramalho.

Changed prior to commit:
  https://reviews.llvm.org/D47305?vs=148328=151285#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D47305

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
  cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp

Index: cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp
===
--- cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp
+++ cfe/trunk/test/Analysis/cxx17-mandatory-elision.cpp
@@ -3,6 +3,26 @@
 
 void clang_analyzer_eval(bool);
 
+namespace variable_functional_cast_crash {
+
+struct A {
+  A(int) {}
+};
+
+void foo() {
+  A a = A(0);
+}
+
+struct B {
+  A a;
+  B(): a(A(0)) {}
+};
+
+} // namespace variable_functional_cast_crash
+
+
+namespace address_vector_tests {
+
 template  struct AddressVector {
   T *buf[10];
   int len;
@@ -56,3 +76,5 @@
   clang_analyzer_eval(v.buf[4] == ); // expected-warning{{TRUE}}
 #endif
 }
+
+} // namespace address_vector_tests
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -590,24 +590,12 @@
   SVal InitVal = state->getSVal(InitEx, LC);
 
   assert(DS->isSingleDecl());
-  if (auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) {
-assert(InitEx->IgnoreImplicit() == CtorExpr);
-(void)CtorExpr;
+  if (getObjectUnderConstruction(state, DS, LC)) {
+state = finishObjectConstruction(state, DS, LC);
 // We constructed the object directly in the variable.
 // No need to bind anything.
 B.generateNode(DS, UpdatedN, state);
   } else {
-// We bound the temp obj region to the CXXConstructExpr. Now recover
-// the lazy compound value when the variable is not a reference.
-if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
-!VD->getType()->isReferenceType()) {
-  if (Optional M =
-  InitVal.getAs()) {
-InitVal = state->getSVal(M->getRegion());
-assert(InitVal.getAs());
-  }
-}
-
 // Recover some path-sensitivity if a scalar value evaluated to
 // UnknownVal.
 if (InitVal.isUnknown()) {
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -125,9 +125,11 @@
   const auto *Var = cast(DS->getSingleDecl());
   SVal LValue = State->getLValue(Var, LCtx);
   QualType Ty = Var->getType();
-  return std::make_pair(
-  State,
-  makeZeroElementRegion(State, LValue, Ty, CallOpts.IsArrayCtorOrDtor));
+  LValue =
+  makeZeroElementRegion(State, LValue, Ty, CallOpts.IsArrayCtorOrDtor);
+  State =
+  addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, LValue);
+  return std::make_pair(State, LValue);
 }
 case ConstructionContext::SimpleConstructorInitializerKind: {
   const auto *ICC = cast(CC);
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -193,23 +193,6 @@
   return RuntimeCallee->getCanonicalDecl() != StaticDecl->getCanonicalDecl();
 }
 
-/// Returns true if the CXXConstructExpr \p E was intended to construct a
-/// prvalue for the region in \p V.
-///
-/// Note that we can't just test for rvalue vs. glvalue because
-/// CXXConstructExprs embedded in DeclStmts and initializers are considered
-/// rvalues by the AST, and the analyzer would like to treat them as lvalues.
-static bool isTemporaryPRValue(const CXXConstructExpr *E, SVal V) {
-  if (E->isGLValue())
-return false;
-
-  const MemRegion *MR = V.getAsRegion();
-  if (!MR)
-return false;
-
-  return isa(MR);
-}
-
 /// The call exit is simulated with a sequence of nodes, which occur between
 /// CallExitBegin and CallExitEnd. The following operations occur between the
 /// two program points:
@@ -269,11 +252,7 @@
   loc::MemRegionVal This =
 svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
   SVal ThisV = state->getSVal(This);
-
-  // If the constructed object is a temporary prvalue, get its bindings.
-  if 

[PATCH] D47304: [analyzer] NFC: Merge the functions for obtaining constructed object location and storing this location for later use.

2018-06-13 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC334678: [analyzer] NFC: Merge code for finding and tracking 
construction target. (authored by dergachev, committed by ).
Herald added a subscriber: mikhail.ramalho.

Repository:
  rC Clang

https://reviews.llvm.org/D47304

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp

Index: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -744,14 +744,15 @@
   /// constructing into an existing region.
   const CXXConstructExpr *findDirectConstructorForCurrentCFGElement();
 
-  /// For a given constructor, look forward in the current CFG block to
-  /// determine the region into which an object will be constructed by \p CE.
-  /// When the lookahead fails, a temporary region is returned, and the
+  /// Update the program state with all the path-sensitive information
+  /// that's necessary to perform construction of an object with a given
+  /// syntactic construction context. If the construction context is unavailable
+  /// or unusable for any reason, a dummy temporary region is returned, and the
   /// IsConstructorWithImproperlyModeledTargetRegion flag is set in \p CallOpts.
-  SVal getLocationForConstructedObject(const CXXConstructExpr *CE,
-   ExplodedNode *Pred,
-   const ConstructionContext *CC,
-   EvalCallOptions );
+  /// Returns the updated program state and the new object's this-region.
+  std::pair prepareForObjectConstruction(
+  const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
+  const ConstructionContext *CC, EvalCallOptions );
 
   /// Store the location of a C++ object corresponding to a statement
   /// until the statement is actually encountered. For example, if a DeclStmt
@@ -782,14 +783,6 @@
   static bool areAllObjectsFullyConstructed(ProgramStateRef State,
 const LocationContext *FromLC,
 const LocationContext *ToLC);
-
-  /// Adds an initialized temporary and/or a materialization, whichever is
-  /// necessary, by looking at the whole construction context. Handles
-  /// function return values, which need the construction context of the parent
-  /// stack frame, automagically.
-  ProgramStateRef markStatementsCorrespondingToConstructedObject(
-  ProgramStateRef State, const ConstructionContext *CC,
-  const LocationContext *LC, SVal V);
 };
 
 /// Traits for storing the call processing policy inside GDM.
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -110,13 +110,9 @@
   return LValue;
 }
 
-
-SVal ExprEngine::getLocationForConstructedObject(const CXXConstructExpr *CE,
- ExplodedNode *Pred,
- const ConstructionContext *CC,
- EvalCallOptions ) {
-  const LocationContext *LCtx = Pred->getLocationContext();
-  ProgramStateRef State = Pred->getState();
+std::pair ExprEngine::prepareForObjectConstruction(
+const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
+const ConstructionContext *CC, EvalCallOptions ) {
   MemRegionManager  = getSValBuilder().getRegionManager();
 
   // See if we're constructing an existing region by looking at the
@@ -129,8 +125,9 @@
   const auto *Var = cast(DS->getSingleDecl());
   SVal LValue = State->getLValue(Var, LCtx);
   QualType Ty = Var->getType();
-  return makeZeroElementRegion(State, LValue, Ty,
-   CallOpts.IsArrayCtorOrDtor);
+  return std::make_pair(
+  State,
+  makeZeroElementRegion(State, LValue, Ty, CallOpts.IsArrayCtorOrDtor));
 }
 case ConstructionContext::SimpleConstructorInitializerKind: {
   const auto *ICC = cast(CC);
@@ -154,7 +151,7 @@
   QualType Ty = Field->getType();
   FieldVal = makeZeroElementRegion(State, FieldVal, Ty,
CallOpts.IsArrayCtorOrDtor);
-  return FieldVal;
+  return std::make_pair(State, FieldVal);
 }
 case ConstructionContext::NewAllocatedObjectKind: {
   if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
@@ -167,65 +164,97 @@
 // TODO: In fact, we need to call the constructor for every
 // allocated element, not just the first one!

r334678 - [analyzer] NFC: Merge code for finding and tracking construction target.

2018-06-13 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Wed Jun 13 18:20:12 2018
New Revision: 334678

URL: http://llvm.org/viewvc/llvm-project?rev=334678=rev
Log:
[analyzer] NFC: Merge code for finding and tracking construction target.

When analyzing C++ code, a common operation in the analyzer is to discover
target region for object construction by looking at CFG metadata ("construction
contexts"), and then track the region path-sensitively until object construction
is resolved, where the amount of information, again, depends on construction
context.

Scan construction context only once for both purposes.

Differential Revision: https://reviews.llvm.org/D47304

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=334678=334677=334678=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Wed 
Jun 13 18:20:12 2018
@@ -744,14 +744,15 @@ private:
   /// constructing into an existing region.
   const CXXConstructExpr *findDirectConstructorForCurrentCFGElement();
 
-  /// For a given constructor, look forward in the current CFG block to
-  /// determine the region into which an object will be constructed by \p CE.
-  /// When the lookahead fails, a temporary region is returned, and the
+  /// Update the program state with all the path-sensitive information
+  /// that's necessary to perform construction of an object with a given
+  /// syntactic construction context. If the construction context is 
unavailable
+  /// or unusable for any reason, a dummy temporary region is returned, and the
   /// IsConstructorWithImproperlyModeledTargetRegion flag is set in \p 
CallOpts.
-  SVal getLocationForConstructedObject(const CXXConstructExpr *CE,
-   ExplodedNode *Pred,
-   const ConstructionContext *CC,
-   EvalCallOptions );
+  /// Returns the updated program state and the new object's this-region.
+  std::pair prepareForObjectConstruction(
+  const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
+  const ConstructionContext *CC, EvalCallOptions );
 
   /// Store the location of a C++ object corresponding to a statement
   /// until the statement is actually encountered. For example, if a DeclStmt
@@ -782,14 +783,6 @@ private:
   static bool areAllObjectsFullyConstructed(ProgramStateRef State,
 const LocationContext *FromLC,
 const LocationContext *ToLC);
-
-  /// Adds an initialized temporary and/or a materialization, whichever is
-  /// necessary, by looking at the whole construction context. Handles
-  /// function return values, which need the construction context of the parent
-  /// stack frame, automagically.
-  ProgramStateRef markStatementsCorrespondingToConstructedObject(
-  ProgramStateRef State, const ConstructionContext *CC,
-  const LocationContext *LC, SVal V);
 };
 
 /// Traits for storing the call processing policy inside GDM.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=334678=334677=334678=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed Jun 13 18:20:12 2018
@@ -417,81 +417,6 @@ bool ExprEngine::areAllObjectsFullyConst
   return true;
 }
 
-ProgramStateRef ExprEngine::markStatementsCorrespondingToConstructedObject(
-ProgramStateRef State, const ConstructionContext *CC,
-const LocationContext *LC, SVal V) {
-  if (CC) {
-// If the temporary is being returned from the function, it will be
-// destroyed or lifetime-extended in the caller stack frame.
-if (isa(CC)) {
-  const StackFrameContext *SFC = LC->getCurrentStackFrame();
-  assert(SFC);
-  LC = SFC->getParent();
-  if (!LC) {
-// We are on the top frame. We won't ever need any info
-// for this temporary, so don't set anything.
-return State;
-  }
-  const CFGElement  =
-  (*SFC->getCallSiteBlock())[SFC->getIndex()];
-  auto RTCElem = CallElem.getAs();
-  if (!RTCElem) {
-// We have a parent stack frame, but no construction context for the
-// return value. Give up until we provide the construction context
-  

[PATCH] D48155: Teach Clang to emit address-significance tables.

2018-06-13 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc updated this revision to Diff 151282.
pcc added a comment.

- Add some additional driver tests


https://reviews.llvm.org/D48155

Files:
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/addrsig.c
  clang/test/Driver/addrsig.c

Index: clang/test/Driver/addrsig.c
===
--- /dev/null
+++ clang/test/Driver/addrsig.c
@@ -0,0 +1,8 @@
+// RUN: %clang -### -target x86_64-unknown-linux -c %s 2>&1 | FileCheck -check-prefix=ADDRSIG %s
+// RUN: %clang -### -target x86_64-unknown-linux -fno-integrated-as -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
+// RUN: %clang -### -target x86_64-unknown-linux -fno-integrated-as -faddrsig -c %s 2>&1 | FileCheck -check-prefix=ADDRSIG %s
+// RUN: %clang -### -target x86_64-unknown-linux -fno-addrsig -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
+// RUN: %clang -### -target x86_64-apple-darwin -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
+
+// ADDRSIG: -faddrsig
+// NO-ADDRSIG-NOT: -faddrsig
Index: clang/test/CodeGen/addrsig.c
===
--- /dev/null
+++ clang/test/CodeGen/addrsig.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux -S %s -faddrsig -O -o - | FileCheck --check-prefix=ADDRSIG %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux -S %s -O -o - | FileCheck --check-prefix=NO-ADDRSIG %s
+
+// ADDRSIG: .addrsig
+// ADDRSIG: .addrsig_sym g1
+// ADDRSIG-NOT: .addrsig_sym g2
+
+// NO-ADDRSIG-NOT: .addrsig
+
+extern const int g1[], g2[];
+
+const int *f1() {
+  return g1;
+}
+
+int f2() {
+  return g2[0];
+}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1119,6 +1119,8 @@
 
   Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
 
+  Opts.Addrsig = Args.hasArg(OPT_faddrsig);
+
   return Success;
 }
 
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -4798,6 +4798,11 @@
options::OPT_fno_complete_member_pointers, false))
 CmdArgs.push_back("-fcomplete-member-pointers");
 
+  if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig,
+   getToolChain().getTriple().isOSBinFormatELF() &&
+   getToolChain().useIntegratedAs()))
+CmdArgs.push_back("-faddrsig");
+
   // Finally add the compile command to the compilation.
   if (Args.hasArg(options::OPT__SLASH_fallback) &&
   Output.getType() == types::TY_Object &&
Index: clang/lib/CodeGen/BackendUtil.cpp
===
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -454,6 +454,7 @@
   Options.ExplicitEmulatedTLS = CodeGenOpts.ExplicitEmulatedTLS;
   Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
   Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
+  Options.EmitAddrsig = CodeGenOpts.Addrsig;
 
   if (CodeGenOpts.EnableSplitDwarf)
 Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
Index: clang/include/clang/Frontend/CodeGenOptions.def
===
--- clang/include/clang/Frontend/CodeGenOptions.def
+++ clang/include/clang/Frontend/CodeGenOptions.def
@@ -335,6 +335,9 @@
 /// Whether to emit all vtables
 CODEGENOPT(ForceEmitVTables, 1, 0)
 
+/// Whether to emit an address-significance table into the object file.
+CODEGENOPT(Addrsig, 1, 0)
+
 
 #undef CODEGENOPT
 #undef ENUM_CODEGENOPT
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -758,6 +758,10 @@
 def fno_profile_use : Flag<["-"], "fno-profile-use">,
 Alias;
 
+def faddrsig : Flag<["-"], "faddrsig">, Group, Flags<[CoreOption, CC1Option]>,
+  HelpText<"Emit an address-significance table">;
+def fno_addrsig : Flag<["-"], "fno-addrsig">, Group, Flags<[CoreOption]>,
+  HelpText<"Don't emit an address-significance table">;
 def fblocks : Flag<["-"], "fblocks">, Group, Flags<[CC1Option]>,
   HelpText<"Enable the 'blocks' language feature">;
 def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48155: Teach Clang to emit address-significance tables.

2018-06-13 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc created this revision.
pcc added reviewers: echristo, Bigcheese, rsmith.

By default, we emit an address-significance table on all ELF
targets when the integrated assembler is enabled. The emission of an
address-significance table can be controlled with the -faddrsig and
-fno-addrsig flags.

Depends on https://reviews.llvm.org/D48143


https://reviews.llvm.org/D48155

Files:
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/addrsig.c
  clang/test/Driver/addrsig.c

Index: clang/test/Driver/addrsig.c
===
--- /dev/null
+++ clang/test/Driver/addrsig.c
@@ -0,0 +1,6 @@
+// RUN: %clang -### -target x86_64-unknown-linux -c %s 2>&1 | FileCheck -check-prefix=ADDRSIG %s
+// RUN: %clang -### -target x86_64-unknown-linux -fno-integrated-as -gz -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
+// RUN: %clang -### -target x86_64-apple-darwin -c %s 2>&1 | FileCheck -check-prefix=NO-ADDRSIG %s
+
+// ADDRSIG: -faddrsig
+// NO-ADDRSIG-NOT: -faddrsig
Index: clang/test/CodeGen/addrsig.c
===
--- /dev/null
+++ clang/test/CodeGen/addrsig.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux -S %s -faddrsig -O -o - | FileCheck --check-prefix=ADDRSIG %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux -S %s -O -o - | FileCheck --check-prefix=NO-ADDRSIG %s
+
+// ADDRSIG: .addrsig
+// ADDRSIG: .addrsig_sym g1
+// ADDRSIG-NOT: .addrsig_sym g2
+
+// NO-ADDRSIG-NOT: .addrsig
+
+extern const int g1[], g2[];
+
+const int *f1() {
+  return g1;
+}
+
+int f2() {
+  return g2[0];
+}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1119,6 +1119,8 @@
 
   Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
 
+  Opts.Addrsig = Args.hasArg(OPT_faddrsig);
+
   return Success;
 }
 
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -4798,6 +4798,11 @@
options::OPT_fno_complete_member_pointers, false))
 CmdArgs.push_back("-fcomplete-member-pointers");
 
+  if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig,
+   getToolChain().getTriple().isOSBinFormatELF() &&
+   getToolChain().useIntegratedAs()))
+CmdArgs.push_back("-faddrsig");
+
   // Finally add the compile command to the compilation.
   if (Args.hasArg(options::OPT__SLASH_fallback) &&
   Output.getType() == types::TY_Object &&
Index: clang/lib/CodeGen/BackendUtil.cpp
===
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -454,6 +454,7 @@
   Options.ExplicitEmulatedTLS = CodeGenOpts.ExplicitEmulatedTLS;
   Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
   Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
+  Options.EmitAddrsig = CodeGenOpts.Addrsig;
 
   if (CodeGenOpts.EnableSplitDwarf)
 Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
Index: clang/include/clang/Frontend/CodeGenOptions.def
===
--- clang/include/clang/Frontend/CodeGenOptions.def
+++ clang/include/clang/Frontend/CodeGenOptions.def
@@ -335,6 +335,9 @@
 /// Whether to emit all vtables
 CODEGENOPT(ForceEmitVTables, 1, 0)
 
+/// Whether to emit an address-significance table into the object file.
+CODEGENOPT(Addrsig, 1, 0)
+
 
 #undef CODEGENOPT
 #undef ENUM_CODEGENOPT
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -758,6 +758,10 @@
 def fno_profile_use : Flag<["-"], "fno-profile-use">,
 Alias;
 
+def faddrsig : Flag<["-"], "faddrsig">, Group, Flags<[CoreOption, CC1Option]>,
+  HelpText<"Emit an address-significance table">;
+def fno_addrsig : Flag<["-"], "fno-addrsig">, Group, Flags<[CoreOption]>,
+  HelpText<"Don't emit an address-significance table">;
 def fblocks : Flag<["-"], "fblocks">, Group, Flags<[CC1Option]>,
   HelpText<"Enable the 'blocks' language feature">;
 def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47671: [analyzer] Implement copy elision.

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

> P.S. It seems that one of my currently-on-review patches has introduced a 
> performance regression, i'm investigating it.

Never mind, that was an old version of the patch, i.e. i accidentally fixed 
that regression before uploading the patch to phabricator.


https://reviews.llvm.org/D47671



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47671: [analyzer] Implement copy elision.

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 151279.
NoQ added a comment.

I added an option to disable copy elision on CFG side in 
https://reviews.llvm.org/D47616. The analyzer makes use of it automagically: 
elided constructors are replaced with temporary constructors in the CFG and the 
old behavior is restored.

Tests now test both behaviors and demonstrate that C++17 mandatory copy elision 
works exactly like pre-C++17 optional copy elision, despite underlying AST 
being completely different. Well, most of the time: there's still a bug that 
causes us to think that we need to call a destructor on the elided temporary. 
Thankfully, such destructor would be evaluated conservatively.


https://reviews.llvm.org/D47671

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/cxx17-mandatory-elision.cpp
  test/Analysis/gtest.cpp
  test/Analysis/inlining/temp-dtors-path-notes.cpp
  test/Analysis/lifetime-extension.cpp
  test/Analysis/temporaries.cpp

Index: test/Analysis/temporaries.cpp
===
--- test/Analysis/temporaries.cpp
+++ test/Analysis/temporaries.cpp
@@ -612,107 +612,44 @@
   clang_analyzer_eval(c3.getY() == 2); // expected-warning{{TRUE}}
 
   C c4 = returnTemporaryWithConstruction();
-  clang_analyzer_eval(c4.getX() == 1);
-  clang_analyzer_eval(c4.getY() == 2);
-#ifdef TEMPORARY_DTORS
-  // expected-warning@-3{{TRUE}}
-  // expected-warning@-3{{TRUE}}
-#else
-  // expected-warning@-6{{UNKNOWN}}
-  // expected-warning@-6{{UNKNOWN}}
-#endif
+  clang_analyzer_eval(c4.getX() == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c4.getY() == 2); // expected-warning{{TRUE}}
 
   C c5 = returnTemporaryWithAnotherFunctionWithConstruction();
-  clang_analyzer_eval(c5.getX() == 1);
-  clang_analyzer_eval(c5.getY() == 2);
-#ifdef TEMPORARY_DTORS
-  // expected-warning@-3{{TRUE}}
-  // expected-warning@-3{{TRUE}}
-#else
-  // expected-warning@-6{{UNKNOWN}}
-  // expected-warning@-6{{UNKNOWN}}
-#endif
+  clang_analyzer_eval(c5.getX() == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c5.getY() == 2); // expected-warning{{TRUE}}
 
   C c6 = returnTemporaryWithCopyConstructionWithConstruction();
-  clang_analyzer_eval(c5.getX() == 1);
-  clang_analyzer_eval(c5.getY() == 2);
-#ifdef TEMPORARY_DTORS
-  // expected-warning@-3{{TRUE}}
-  // expected-warning@-3{{TRUE}}
-#else
-  // expected-warning@-6{{UNKNOWN}}
-  // expected-warning@-6{{UNKNOWN}}
-#endif
+  clang_analyzer_eval(c5.getX() == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c5.getY() == 2); // expected-warning{{TRUE}}
 
 #if __cplusplus >= 201103L
 
   C c7 = returnTemporaryWithBraces();
-  clang_analyzer_eval(c7.getX() == 1);
-  clang_analyzer_eval(c7.getY() == 2);
-#ifdef TEMPORARY_DTORS
-  // expected-warning@-3{{TRUE}}
-  // expected-warning@-3{{TRUE}}
-#else
-  // expected-warning@-6{{UNKNOWN}}
-  // expected-warning@-6{{UNKNOWN}}
-#endif
+  clang_analyzer_eval(c7.getX() == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c7.getY() == 2); // expected-warning{{TRUE}}
 
   C c8 = returnTemporaryWithAnotherFunctionWithBraces();
-  clang_analyzer_eval(c8.getX() == 1);
-  clang_analyzer_eval(c8.getY() == 2);
-#ifdef TEMPORARY_DTORS
-  // expected-warning@-3{{TRUE}}
-  // expected-warning@-3{{TRUE}}
-#else
-  // expected-warning@-6{{UNKNOWN}}
-  // expected-warning@-6{{UNKNOWN}}
-#endif
+  clang_analyzer_eval(c8.getX() == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c8.getY() == 2); // expected-warning{{TRUE}}
 
   C c9 = returnTemporaryWithCopyConstructionWithBraces();
-  clang_analyzer_eval(c9.getX() == 1);
-  clang_analyzer_eval(c9.getY() == 2);
-#ifdef TEMPORARY_DTORS
-  // expected-warning@-3{{TRUE}}
-  // expected-warning@-3{{TRUE}}
-#else
-  // expected-warning@-6{{UNKNOWN}}
-  // expected-warning@-6{{UNKNOWN}}
-#endif
+  clang_analyzer_eval(c9.getX() == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c9.getY() == 2); // expected-warning{{TRUE}}
 
 #endif // C++11
 
   D d1 = returnTemporaryWithVariableAndNonTrivialCopy();
-  clang_analyzer_eval(d1.getX() == 1);
-  clang_analyzer_eval(d1.getY() == 2);
-#ifdef TEMPORARY_DTORS
-  // expected-warning@-3{{TRUE}}
-  // expected-warning@-3{{TRUE}}
-#else
-  // expected-warning@-6{{UNKNOWN}}
-  // expected-warning@-6{{UNKNOWN}}
-#endif
+  clang_analyzer_eval(d1.getX() == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(d1.getY() == 2); // expected-warning{{TRUE}}
 
   D d2 = returnTemporaryWithAnotherFunctionWithVariableAndNonTrivialCopy();
-  clang_analyzer_eval(d2.getX() == 1);
-  clang_analyzer_eval(d2.getY() == 2);
-#ifdef TEMPORARY_DTORS
-  // expected-warning@-3{{TRUE}}
-  // expected-warning@-3{{TRUE}}
-#else
-  // expected-warning@-6{{UNKNOWN}}
-  // expected-warning@-6{{UNKNOWN}}
-#endif
+  clang_analyzer_eval(d2.getX() == 1); // expected-warning{{TRUE}}
+  

[PATCH] D47616: [CFG] [analyzer] Explain copy elision through construction contexts.

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 151277.
NoQ added a comment.

Add a flag to disable copy elision. It's convenient to have such flag in the 
CFG because this way all clients will be able to transparently handle it. When 
the option is turned off, elided construction contexts will be replaced with 
simple temporary object construction contexts which need to be handled anyway. 
When construction contexts are disabled entirely, the option has no effect.


https://reviews.llvm.org/D47616

Files:
  include/clang/Analysis/AnalysisDeclContext.h
  include/clang/Analysis/CFG.h
  include/clang/Analysis/ConstructionContext.h
  include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
  lib/Analysis/AnalysisDeclContext.cpp
  lib/Analysis/CFG.cpp
  lib/Analysis/ConstructionContext.cpp
  lib/StaticAnalyzer/Core/AnalysisManager.cpp
  lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/analyzer-config.c
  test/Analysis/analyzer-config.cpp
  test/Analysis/cfg-rich-constructors.cpp
  test/Analysis/temp-obj-dtors-cfg-output.cpp

Index: test/Analysis/temp-obj-dtors-cfg-output.cpp
===
--- test/Analysis/temp-obj-dtors-cfg-output.cpp
+++ test/Analysis/temp-obj-dtors-cfg-output.cpp
@@ -235,7 +235,7 @@
 // CHECK: Succs (1): B1
 // CHECK:   [B1]
 // WARNINGS: 1: A() (CXXConstructExpr, class A)
-// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], [B1.4], class A)
+// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class A)
 // CHECK: 2: [B1.1] (BindTemporary)
 // CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A)
 // CHECK: 4: [B1.3]
@@ -295,7 +295,7 @@
 // CHECK: Succs (1): B1
 // CHECK:   [B1]
 // WARNINGS: 1: A() (CXXConstructExpr, class A)
-// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], [B1.4], class A)
+// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class A)
 // CHECK: 2: [B1.1] (BindTemporary)
 // CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A)
 // CHECK: 4: [B1.3]
@@ -550,12 +550,12 @@
 // CHECK: Succs (2): B6 B5
 // CHECK:   [B8]
 // WARNINGS: 1: A() (CXXConstructExpr, class A)
-// ANALYZER: 1: A() (CXXConstructExpr, [B8.2], [B8.4], class A)
+// ANALYZER: 1: A() (CXXConstructExpr, [B8.2], [B8.4], [B8.5], class A)
 // CHECK: 2: [B8.1] (BindTemporary)
 // CHECK: 3: [B8.2] (ImplicitCastExpr, NoOp, const class A)
 // CHECK: 4: [B8.3]
 // WARNINGS: 5: [B8.4] (CXXConstructExpr, class A)
-// ANALYZER: 5: [B8.4] (CXXConstructExpr, [B8.6], [B7.3], class A)
+// ANALYZER: 5: [B8.4] (CXXConstructExpr, [B8.6], [B7.3], [B7.4], class A)
 // CHECK: 6: [B8.5] (BindTemporary)
 // CHECK: Preds (1): B10
 // CHECK: Succs (1): B7
@@ -570,13 +570,13 @@
 // CHECK: 7: [B9.6] (ImplicitCastExpr, NoOp, const class A)
 // CHECK: 8: [B9.7]
 // WARNINGS: 9: [B9.8] (CXXConstructExpr, class A)
-// ANALYZER: 9: [B9.8] (CXXConstructExpr, [B9.10], [B9.13], class A)
+// ANALYZER: 9: [B9.8] (CXXConstructExpr, [B9.10], [B9.13], [B9.14], class A)
 // CHECK:10: [B9.9] (BindTemporary)
 // CHECK:11: A([B9.10]) (CXXFunctionalCastExpr, ConstructorConversion, class A)
 // CHECK:12: [B9.11] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:13: [B9.12]
 // WARNINGS:14: [B9.13] (CXXConstructExpr, class A)
-// ANALYZER:14: [B9.13] (CXXConstructExpr, [B9.15], [B7.3], class A)
+// ANALYZER:14: [B9.13] (CXXConstructExpr, [B9.15], [B7.3], [B7.4], class A)
 // CHECK:15: [B9.14] (BindTemporary)
 // CHECK: Preds (1): B10
 // CHECK: Succs (1): B7
@@ -680,7 +680,7 @@
 // CHECK: Succs (1): B0
 // CHECK:   [B4]
 // WARNINGS: 1: C() (CXXConstructExpr, struct C)
-// ANALYZER: 1: C() (CXXConstructExpr, [B4.2], [B4.4], struct C)
+// ANALYZER: 1: C() (CXXConstructExpr, [B4.2], [B4.4], [B4.5], struct C)
 // CHECK: 2: [B4.1] (BindTemporary)
 // CHECK: 3: [B4.2] (ImplicitCastExpr, NoOp, const struct C)
 // CHECK: 4: [B4.3]
@@ -733,7 +733,7 @@
 // CHECK: Succs (1): B0
 // CHECK:   [B3]
 // CXX98-WARNINGS: 1: D() (CXXConstructExpr, struct D)
-// CXX98-ANALYZER: 1: D() (CXXConstructExpr, [B3.3], struct D)
+// CXX98-ANALYZER: 1: D() (CXXConstructExpr, [B3.3], [B3.4], struct D)
 // CXX98: 2: [B3.1] (ImplicitCastExpr, NoOp, const struct D)
 // CXX98: 3: [B3.2]
 // CXX98-WARNINGS: 4: [B3.3] (CXXConstructExpr, struct D)
@@ -745,7 +745,7 @@
 // CXX98: 9: [B3.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CXX98: T: if [B3.9]
 // CXX11-WARNINGS: 1: D() (CXXConstructExpr, struct D)
-// CXX11-ANALYZER: 1: D() (CXXConstructExpr, [B3.2], struct D)
+// CXX11-ANALYZER: 1: D() (CXXConstructExpr, [B3.2], [B3.3], struct D)
 // CXX11: 2: [B3.1]
 // CXX11-WARNINGS: 3: [B3.2] (CXXConstructExpr, struct D)
 // CXX11-ANALYZER: 3: [B3.2] (CXXConstructExpr, [B3.4], struct D)
@@ -789,7 +789,7 @@
 // CHECK: 

[PATCH] D47616: [CFG] [analyzer] Explain copy elision through construction contexts.

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added inline comments.



Comment at: include/clang/Analysis/ConstructionContext.h:351
+
+  explicit SimpleTemporaryObjectConstructionContext(
+  const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE)

MTC wrote:
> MTC wrote:
> > `explicit` useless?
> I'm wrong here, maybe there is some use of 
> `SimpleTemporaryObjectConstructionContext({ , })`, sorry to bother!
Well, i really doubt it'd ever matter (given that the constructor is also 
private, we can pretty much control all constructions by hand) but i think it's 
a good practice to add the restriction unless implicit construction is actually 
important.


https://reviews.llvm.org/D47616



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47667: [CFG] [analyzer] Remove unnecessary CXXBindTemporaryExpr from lifetime-extended temporary construction contexts.

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 151278.
NoQ added a comment.
Herald added a subscriber: mikhail.ramalho.

Rebase.


https://reviews.llvm.org/D47667

Files:
  lib/Analysis/ConstructionContext.cpp
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/auto-obj-dtors-cfg-output.cpp
  test/Analysis/cfg-rich-constructors.cpp
  test/Analysis/temp-obj-dtors-cfg-output.cpp

Index: test/Analysis/temp-obj-dtors-cfg-output.cpp
===
--- test/Analysis/temp-obj-dtors-cfg-output.cpp
+++ test/Analysis/temp-obj-dtors-cfg-output.cpp
@@ -857,7 +857,7 @@
 // CHECK: 3: [B11.2] (ImplicitCastExpr, NoOp, const class A)
 // CHECK: 4: [B11.3]
 // WARNINGS: 5: [B11.4] (CXXConstructExpr, class A)
-// ANALYZER: 5: [B11.4] (CXXConstructExpr, [B11.6], [B10.3], class A)
+// ANALYZER: 5: [B11.4] (CXXConstructExpr, [B10.3], class A)
 // CHECK: 6: [B11.5] (BindTemporary)
 // CHECK: Preds (1): B13
 // CHECK: Succs (1): B10
@@ -878,7 +878,7 @@
 // CHECK:12: [B12.11] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:13: [B12.12]
 // WARNINGS:14: [B12.13] (CXXConstructExpr, class A)
-// ANALYZER:14: [B12.13] (CXXConstructExpr, [B12.15], [B10.3], class A)
+// ANALYZER:14: [B12.13] (CXXConstructExpr, [B10.3], class A)
 // CHECK:15: [B12.14] (BindTemporary)
 // CHECK: Preds (1): B13
 // CHECK: Succs (1): B10
@@ -1104,7 +1104,7 @@
 // CHECK: Succs (1): B1
 // CHECK:   [B1]
 // WARNINGS: 1: A() (CXXConstructExpr, class A)
-// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], [B1.4], class A)
+// ANALYZER: 1: A() (CXXConstructExpr, [B1.4], class A)
 // CHECK: 2: [B1.1] (BindTemporary)
 // CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A)
 // CHECK: 4: [B1.3]
@@ -1150,7 +1150,7 @@
 // CHECK: 1: A::make
 // CHECK: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class A (*)(void))
 // WARNINGS: 3: [B1.2]()
-// ANALYZER: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6])
+// ANALYZER: 3: [B1.2]() (CXXRecordTypedCall, [B1.6])
 // CHECK: 4: [B1.3] (BindTemporary)
 // CHECK: 5: [B1.4] (ImplicitCastExpr, NoOp, const class A)
 // CHECK: 6: [B1.5]
Index: test/Analysis/cfg-rich-constructors.cpp
===
--- test/Analysis/cfg-rich-constructors.cpp
+++ test/Analysis/cfg-rich-constructors.cpp
@@ -597,7 +597,7 @@
 
 // CHECK: void referenceVariableWithConstructor()
 // CHECK:  1: 0
-// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.3], [B1.4], const class temporary_object_expr_with_dtors::D)
+// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.4], const class temporary_object_expr_with_dtors::D)
 // CHECK-NEXT: 3: [B1.2] (BindTemporary)
 // CHECK-NEXT: 4: [B1.3]
 // CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D (0);
@@ -607,7 +607,7 @@
 }
 
 // CHECK: void referenceVariableWithInitializer()
-// CHECK:  1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], [B1.4], class temporary_object_expr_with_dtors::D)
+// CHECK:  1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.4], class temporary_object_expr_with_dtors::D)
 // CHECK-NEXT: 2: [B1.1] (BindTemporary)
 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
 // CHECK-NEXT: 4: [B1.3]
@@ -638,7 +638,7 @@
 // CXX11-NEXT: 4: [B5.3] (BindTemporary)
 // CXX11-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
 // CXX11-NEXT: 6: [B5.5]
-// CXX11-NEXT: 7: [B5.6] (CXXConstructExpr, [B5.8], [B4.3], class temporary_object_expr_with_dtors::D)
+// CXX11-NEXT: 7: [B5.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D)
 // CXX11-NEXT: 8: [B5.7] (BindTemporary)
 // CXX11:[B6]
 // CXX11-NEXT: 1: 0
@@ -648,7 +648,7 @@
 // CXX11-NEXT: 4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D)
 // CXX11-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
 // CXX11-NEXT: 6: [B6.5]
-// CXX11-NEXT: 7: [B6.6] (CXXConstructExpr, [B6.8], [B4.3], class temporary_object_expr_with_dtors::D)
+// CXX11-NEXT: 7: [B6.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D)
 // CXX11-NEXT: 8: [B6.7] (BindTemporary)
 // CXX11:[B7]
 // CXX11-NEXT: 1: coin
@@ -663,11 +663,11 @@
 // CXX17:[B2]
 // CXX17-NEXT: 1: D::get
 // CXX17-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void))
-// CXX17-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4], [B1.3])
+// CXX17-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B1.3])
 // CXX17-NEXT: 4: [B2.3] (BindTemporary)
 // CXX17:[B3]
 // CXX17-NEXT: 1: 0
-// CXX17-NEXT: 2: [B3.1] 

r334677 - P0096R5, P0941R2: Update to match latest feature test macro specification.

2018-06-13 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Wed Jun 13 17:40:20 2018
New Revision: 334677

URL: http://llvm.org/viewvc/llvm-project?rev=334677=rev
Log:
P0096R5, P0941R2: Update to match latest feature test macro specification.

Modified:
cfe/trunk/lib/Frontend/InitPreprocessor.cpp
cfe/trunk/test/Lexer/cxx-features.cpp
cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=334677=334676=334677=diff
==
--- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original)
+++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Wed Jun 13 17:40:20 2018
@@ -487,82 +487,86 @@ static void InitializeCPlusPlusFeatureTe
  MacroBuilder ) {
   // C++98 features.
   if (LangOpts.RTTI)
-Builder.defineMacro("__cpp_rtti", "199711");
+Builder.defineMacro("__cpp_rtti", "199711L");
   if (LangOpts.CXXExceptions)
-Builder.defineMacro("__cpp_exceptions", "199711");
+Builder.defineMacro("__cpp_exceptions", "199711L");
 
   // C++11 features.
   if (LangOpts.CPlusPlus11) {
-Builder.defineMacro("__cpp_unicode_characters", "200704");
-Builder.defineMacro("__cpp_raw_strings", "200710");
-Builder.defineMacro("__cpp_unicode_literals", "200710");
-Builder.defineMacro("__cpp_user_defined_literals", "200809");
-Builder.defineMacro("__cpp_lambdas", "200907");
+Builder.defineMacro("__cpp_unicode_characters", "200704L");
+Builder.defineMacro("__cpp_raw_strings", "200710L");
+Builder.defineMacro("__cpp_unicode_literals", "200710L");
+Builder.defineMacro("__cpp_user_defined_literals", "200809L");
+Builder.defineMacro("__cpp_lambdas", "200907L");
 Builder.defineMacro("__cpp_constexpr",
-LangOpts.CPlusPlus17 ? "201603" :
-LangOpts.CPlusPlus14 ? "201304" : "200704");
+LangOpts.CPlusPlus17 ? "201603L" :
+LangOpts.CPlusPlus14 ? "201304L" : "200704");
 Builder.defineMacro("__cpp_range_based_for",
-LangOpts.CPlusPlus17 ? "201603" : "200907");
+LangOpts.CPlusPlus17 ? "201603L" : "200907");
 Builder.defineMacro("__cpp_static_assert",
-LangOpts.CPlusPlus17 ? "201411" : "200410");
-Builder.defineMacro("__cpp_decltype", "200707");
-Builder.defineMacro("__cpp_attributes", "200809");
-Builder.defineMacro("__cpp_rvalue_references", "200610");
-Builder.defineMacro("__cpp_variadic_templates", "200704");
-Builder.defineMacro("__cpp_initializer_lists", "200806");
-Builder.defineMacro("__cpp_delegating_constructors", "200604");
-Builder.defineMacro("__cpp_nsdmi", "200809");
-Builder.defineMacro("__cpp_inheriting_constructors", "201511");
-Builder.defineMacro("__cpp_ref_qualifiers", "200710");
-Builder.defineMacro("__cpp_alias_templates", "200704");
+LangOpts.CPlusPlus17 ? "201411L" : "200410");
+Builder.defineMacro("__cpp_decltype", "200707L");
+Builder.defineMacro("__cpp_attributes", "200809L");
+Builder.defineMacro("__cpp_rvalue_references", "200610L");
+Builder.defineMacro("__cpp_variadic_templates", "200704L");
+Builder.defineMacro("__cpp_initializer_lists", "200806L");
+Builder.defineMacro("__cpp_delegating_constructors", "200604L");
+Builder.defineMacro("__cpp_nsdmi", "200809L");
+Builder.defineMacro("__cpp_inheriting_constructors", "201511L");
+Builder.defineMacro("__cpp_ref_qualifiers", "200710L");
+Builder.defineMacro("__cpp_alias_templates", "200704L");
   }
   if (LangOpts.ThreadsafeStatics)
-Builder.defineMacro("__cpp_threadsafe_static_init", "200806");
+Builder.defineMacro("__cpp_threadsafe_static_init", "200806L");
 
   // C++14 features.
   if (LangOpts.CPlusPlus14) {
-Builder.defineMacro("__cpp_binary_literals", "201304");
-Builder.defineMacro("__cpp_digit_separators", "201309");
-Builder.defineMacro("__cpp_init_captures", "201304");
-Builder.defineMacro("__cpp_generic_lambdas", "201304");
-Builder.defineMacro("__cpp_decltype_auto", "201304");
-Builder.defineMacro("__cpp_return_type_deduction", "201304");
-Builder.defineMacro("__cpp_aggregate_nsdmi", "201304");
-Builder.defineMacro("__cpp_variable_templates", "201304");
+Builder.defineMacro("__cpp_binary_literals", "201304L");
+Builder.defineMacro("__cpp_digit_separators", "201309L");
+Builder.defineMacro("__cpp_init_captures", "201304L");
+Builder.defineMacro("__cpp_generic_lambdas", "201304L");
+Builder.defineMacro("__cpp_decltype_auto", "201304L");
+Builder.defineMacro("__cpp_return_type_deduction", "201304L");
+Builder.defineMacro("__cpp_aggregate_nsdmi", "201304L");
+Builder.defineMacro("__cpp_variable_templates", "201304L");
   }
   if (LangOpts.SizedDeallocation)
-

[PATCH] D47658: [analyzer] Re-enable lifetime extension for temporaries with destructors and bring back static temporaries.

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 151276.
NoQ marked an inline comment as done.
NoQ added a comment.
Herald added a subscriber: mikhail.ramalho.

Fxd.


https://reviews.llvm.org/D47658

Files:
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/lifetime-extension.cpp
  test/Analysis/temporaries-callback-order.cpp

Index: test/Analysis/temporaries-callback-order.cpp
===
--- test/Analysis/temporaries-callback-order.cpp
+++ test/Analysis/temporaries-callback-order.cpp
@@ -8,11 +8,7 @@
 };
 
 void testTemporaries() {
-  // This triggers RegionChanges twice:
-  // - Once for zero-initialization of the structure.
-  // - Once for creating a temporary region and copying the structure there.
-  // FIXME: This code shouldn't really produce the extra temporary, however
-  // that's how we behave for now.
+  // This triggers RegionChanges once for zero-initialization of the structure.
   Sub().m();
 }
 
@@ -29,7 +25,6 @@
 
 // testTemporaries():
 // CHECK-NEXT: RegionChanges
-// CHECK-NEXT: RegionChanges
 
 // Make sure there's no further output.
 // CHECK-NOT: Bind
Index: test/Analysis/lifetime-extension.cpp
===
--- test/Analysis/lifetime-extension.cpp
+++ test/Analysis/lifetime-extension.cpp
@@ -234,25 +234,24 @@
 } // end namespace maintain_original_object_address_on_move
 
 namespace maintain_address_of_copies {
-class C;
 
-struct AddressVector {
-  C *buf[10];
+template  struct AddressVector {
+  const T *buf[10];
   int len;
 
   AddressVector() : len(0) {}
 
-  void push(C *c) {
-buf[len] = c;
+  void push(const T *t) {
+buf[len] = t;
 ++len;
   }
 };
 
 class C {
-  AddressVector 
+  AddressVector 
 
 public:
-  C(AddressVector ) : v(v) { v.push(this); }
+  C(AddressVector ) : v(v) { v.push(this); }
   ~C() { v.push(this); }
 
 #ifdef MOVES
@@ -268,11 +267,11 @@
 #endif
   } // no-warning
 
-  static C make(AddressVector ) { return C(v); }
+  static C make(AddressVector ) { return C(v); }
 };
 
 void f1() {
-  AddressVector v;
+  AddressVector v;
   {
 C c = C(v);
   }
@@ -296,7 +295,7 @@
 }
 
 void f2() {
-  AddressVector v;
+  AddressVector v;
   {
 const C  = C::make(v);
   }
@@ -320,7 +319,7 @@
 }
 
 void f3() {
-  AddressVector v;
+  AddressVector v;
   {
 C & = C::make(v);
   }
@@ -343,12 +342,12 @@
 #endif
 }
 
-C doubleMake(AddressVector ) {
+C doubleMake(AddressVector ) {
   return C::make(v);
 }
 
 void f4() {
-  AddressVector v;
+  AddressVector v;
   {
 C c = doubleMake(v);
   }
@@ -382,4 +381,18 @@
   // expected-warning@-12{{UNKNOWN}}
 #endif
 }
+
+class NoDtor {
+  AddressVector 
+
+public:
+  NoDtor(AddressVector ) : v(v) { v.push(this); }
+};
+
+void f5() {
+  AddressVector v;
+  const NoDtor  = NoDtor(v);
+  clang_analyzer_eval(v.buf[0] == ); // expected-warning{{TRUE}}
+}
+
 } // end namespace maintain_address_of_copies
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -214,12 +214,6 @@
   const CXXBindTemporaryExpr *BTE = TCC->getCXXBindTemporaryExpr();
   const MaterializeTemporaryExpr *MTE = TCC->getMaterializedTemporaryExpr();
 
-  if (!BTE) {
-// FIXME: Lifetime extension for temporaries without destructors
-// is not implemented yet.
-MTE = nullptr;
-  }
-
   if (MTE) {
 if (const ValueDecl *VD = MTE->getExtendingDecl()) {
   assert(MTE->getStorageDuration() != SD_FullExpression);
@@ -234,16 +228,20 @@
 }
   }
 
+  SVal V = UnknownVal();
   if (MTE && MTE->getStorageDuration() != SD_FullExpression) {
 // If the temporary is lifetime-extended, don't save the BTE,
 // because we don't need a temporary destructor, but an automatic
 // destructor.
 BTE = nullptr;
+
+if (MTE->getStorageDuration() == SD_Static ||
+MTE->getStorageDuration() == SD_Thread)
+  V = loc::MemRegionVal(MRMgr.getCXXStaticTempObjectRegion(E));
   }
 
-  // FIXME: Support temporaries lifetime-extended via static references.
-  // They'd need a getCXXStaticTempObjectRegion().
-  SVal V = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
+  if (V.isUnknown())
+V = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
 
   if (BTE)
 State = addObjectUnderConstruction(State, BTE, LCtx, V);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47658: [analyzer] Re-enable lifetime extension for temporaries with destructors and bring back static temporaries.

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added inline comments.



Comment at: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp:234
+  SVal V = UnknownVal();
+  if (MTE) {
+if (MTE->getStorageDuration() != SD_FullExpression) {

MTC wrote:
> An unrelated question. I want to know, what considerations are you based on 
> not continue to use short circuit style : )?
Whoops accidental^^


https://reviews.llvm.org/D47658



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[libcxx] r334675 - [libcxx] [test] Update msvc_stdlib_force_include.hpp.

2018-06-13 Thread Stephan T. Lavavej via cfe-commits
Author: stl_msft
Date: Wed Jun 13 17:12:14 2018
New Revision: 334675

URL: http://llvm.org/viewvc/llvm-project?rev=334675=rev
Log:
[libcxx] [test] Update msvc_stdlib_force_include.hpp.

MSVC's STL removed _SCL_SECURE_NO_WARNINGS.

MSVC's STL implemented feature-test macros.

Modified:
libcxx/trunk/test/support/msvc_stdlib_force_include.hpp

Modified: libcxx/trunk/test/support/msvc_stdlib_force_include.hpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/msvc_stdlib_force_include.hpp?rev=334675=334674=334675=diff
==
--- libcxx/trunk/test/support/msvc_stdlib_force_include.hpp (original)
+++ libcxx/trunk/test/support/msvc_stdlib_force_include.hpp Wed Jun 13 17:12:14 
2018
@@ -73,9 +73,6 @@ const AssertionDialogAvoider assertion_d
 // atomic_is_lock_free.pass.cpp needs this VS 2015 Update 2 fix.
 #define _ENABLE_ATOMIC_ALIGNMENT_FIX
 
-// Silence warnings about raw pointers and other unchecked iterators.
-#define _SCL_SECURE_NO_WARNINGS
-
 // Silence warnings about features that are deprecated in C++17.
 #define _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
 #endif // _LIBCXX_IN_DEVCRT
@@ -88,12 +85,4 @@ const AssertionDialogAvoider assertion_d
 #define TEST_STD_VER 14
 #endif // _HAS_CXX17
 
-// Simulate library feature-test macros.
-#define __cpp_lib_invoke 201411
-#define __cpp_lib_void_t 201411
-
-#if _HAS_CXX17
-#define __cpp_lib_atomic_is_always_lock_free 201603
-#endif // _HAS_CXX17
-
 #endif // SUPPORT_MSVC_STDLIB_FORCE_INCLUDE_HPP


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[libcxx] r334676 - [libcxx] [test] Strip trailing whitespace. NFC.

2018-06-13 Thread Stephan T. Lavavej via cfe-commits
Author: stl_msft
Date: Wed Jun 13 17:12:20 2018
New Revision: 334676

URL: http://llvm.org/viewvc/llvm-project?rev=334676=rev
Log:
[libcxx] [test] Strip trailing whitespace. NFC.

Modified:

libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.fail.cpp

libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.pass.cpp

libcxx/trunk/test/std/containers/container.adaptors/queue/queue.cons/deduct.fail.cpp

libcxx/trunk/test/std/containers/container.adaptors/queue/queue.cons/deduct.pass.cpp

libcxx/trunk/test/std/containers/container.adaptors/stack/stack.cons/deduct.fail.cpp

libcxx/trunk/test/std/containers/container.adaptors/stack/stack.cons/deduct.pass.cpp
libcxx/trunk/test/std/containers/sequences/deque/deque.cons/deduct.fail.cpp
libcxx/trunk/test/std/containers/sequences/deque/deque.cons/deduct.pass.cpp

libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.fail.cpp

libcxx/trunk/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.pass.cpp
libcxx/trunk/test/std/containers/sequences/list/list.cons/deduct.fail.cpp
libcxx/trunk/test/std/containers/sequences/list/list.cons/deduct.pass.cpp

libcxx/trunk/test/std/containers/sequences/vector/vector.cons/deduct.fail.cpp

libcxx/trunk/test/std/containers/sequences/vector/vector.cons/deduct.pass.cpp

libcxx/trunk/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp
libcxx/trunk/test/std/re/re.regex/re.regex.construct/deduct.fail.cpp
libcxx/trunk/test/std/re/re.regex/re.regex.construct/deduct.pass.cpp

libcxx/trunk/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.fail.cpp

libcxx/trunk/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp

Modified: 
libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.fail.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.fail.cpp?rev=334676=334675=334676=diff
==
--- 
libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.fail.cpp
 (original)
+++ 
libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.fail.cpp
 Wed Jun 13 17:12:20 2018
@@ -19,7 +19,7 @@
 
 
 int main()
-{  
+{
 //  Test the explicit deduction guides
 {
 //  queue(Compare, Container, const Alloc);
@@ -35,7 +35,7 @@ int main()
 }
 
 {
-//  priority_queue(Iter, Iter, Comp)  
+//  priority_queue(Iter, Iter, Comp)
 //  int is not an iterator
 std::priority_queue pri(15, 17, std::greater());  // 
expected-error {{no viable constructor or deduction guide for deduction of 
template arguments of 'priority_queue'}}
 }

Modified: 
libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.pass.cpp?rev=334676=334675=334676=diff
==
--- 
libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.pass.cpp
 Wed Jun 13 17:12:20 2018
@@ -14,17 +14,17 @@
 // template
 // priority_queue(Compare, Container)
 // -> priority_queue;
-// 
+//
 // template::value_type>,
 //  class Container = vector::value_type>>
 // priority_queue(InputIterator, InputIterator, Compare = Compare(), Container 
= Container())
 // -> priority_queue::value_type, 
Container, Compare>;
-// 
+//
 // template
 // priority_queue(Compare, Container, Allocator)
 // -> priority_queue;
-
+
 
 #include 
 #include 
@@ -41,7 +41,7 @@ struct A {};
 
 int main()
 {
-  
+
 //  Test the explicit deduction guides
 {
 std::vector v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
@@ -56,7 +56,7 @@ int main()
 std::vector> v{10, 11, 12, 13, 14, 15, 16, 17, 
18, 19 };
 std::priority_queue pri(std::greater(), v, test_allocator(2)); 
// priority_queue(Compare, Container, Allocator)
 
-static_assert(std::is_same_v>, std::greater>>, "");
 assert(pri.size() == v.size());
 assert(pri.top() == 10);

Modified: 
libcxx/trunk/test/std/containers/container.adaptors/queue/queue.cons/deduct.fail.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/container.adaptors/queue/queue.cons/deduct.fail.cpp?rev=334676=334675=334676=diff
==
--- 
libcxx/trunk/test/std/containers/container.adaptors/queue/queue.cons/deduct.fail.cpp
 (original)
+++ 

r334674 - [www] Update cxx_status page for Rapperswil motions.

2018-06-13 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Wed Jun 13 17:05:28 2018
New Revision: 334674

URL: http://llvm.org/viewvc/llvm-project?rev=334674=rev
Log:
[www] Update cxx_status page for Rapperswil motions.

Modified:
cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/www/cxx_status.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=334674=334673=334674=diff
==
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Wed Jun 13 17:05:28 2018
@@ -844,10 +844,14 @@ as the draft C++2a standard evolves.
   Clang 6
 
 
-  __VA_OPT__ for preprocessor comma elision
+  __VA_OPT__ for preprocessor comma elision
   http://wg21.link/p0306r4;>P0306R4
   Clang 6
 
+   
+http://wg21.link/p1042r1;>P1042R1
+Partial
+  
 
   Designated initializers
   http://wg21.link/p0329r4;>P0329R4
@@ -883,13 +887,16 @@ as the draft C++2a standard evolves.
   No
 
 
-  Consistent comparison (operator=)
+  Consistent comparison (operator=)
   http://wg21.link/p0515r3;>P0515R3
-  Partial
+  Partial
 

 http://wg21.link/p0905r1;>P0905R1
   
+   
+http://wg21.link/p1120r0;>P1120R0
+  
 
   Access checking on specializations
   http://wg21.link/p0692r1;>P0692R1
@@ -926,6 +933,42 @@ as the draft C++2a standard evolves.
   http://wg21.link/p0780r2;>P0780R2
   No
 
+
+
+  Class types as non-type template parameters
+  http://wg21.link/p0732r2;>P0732R2
+  No
+
+
+  Destroying operator delete
+  http://wg21.link/p0722r3;>P0722R3
+  Clang 6
+
+
+  Virtual function calls in constant expressions
+  http://wg21.link/p1064r0;>P1064R0
+  No
+
+
+  Prohibit aggregates with user-declared constructors
+  http://wg21.link/p1008r1;>P1008R1
+  No
+
+
+  Contracts
+  http://wg21.link/p0542r5;>P0542R5
+  No
+
+
+  Feature test macros
+  http://wg21.link/p0941r2;>P0941R2
+  (see below)
+
+
+  explicit(bool)
+  http://wg21.link/p0892r2;>P0892R2
+  No
+
 
 
 
@@ -958,7 +1001,7 @@ and library features that are not part o
 Compiler flag
 Available in Clang?
  
-
+
   SD-6: SG10 feature test recommendations
   http://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations;>SD-6
   N/A


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r334673 - Driver: De-duplicate some code. NFCI.

2018-06-13 Thread Peter Collingbourne via cfe-commits
Author: pcc
Date: Wed Jun 13 17:03:41 2018
New Revision: 334673

URL: http://llvm.org/viewvc/llvm-project?rev=334673=rev
Log:
Driver: De-duplicate some code. NFCI.

Modified:
cfe/trunk/lib/Driver/ToolChains/Clang.cpp

Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=334673=334672=334673=diff
==
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Wed Jun 13 17:03:41 2018
@@ -3501,8 +3501,7 @@ void Clang::ConstructJob(Compilation ,
   Args.hasArg(options::OPT_dA))
 CmdArgs.push_back("-masm-verbose");
 
-  if (!Args.hasFlag(options::OPT_fintegrated_as, 
options::OPT_fno_integrated_as,
-IsIntegratedAssemblerDefault))
+  if (!getToolChain().useIntegratedAs())
 CmdArgs.push_back("-no-integrated-as");
 
   if (Args.hasArg(options::OPT_fdebug_pass_structure)) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47567: Implement CFI for indirect calls via a member function pointer.

2018-06-13 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc updated this revision to Diff 151272.
pcc added a comment.

- Add some more documentation to ControlFlowIntegrity.rst


https://reviews.llvm.org/D47567

Files:
  clang/docs/ControlFlowIntegrity.rst
  clang/docs/LTOVisibility.rst
  clang/include/clang/Basic/Sanitizers.def
  clang/lib/CodeGen/CGClass.cpp
  clang/lib/CodeGen/CGVTables.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  clang/lib/Driver/ToolChains/MSVC.cpp
  clang/test/CodeGenCXX/cfi-mfcall-incomplete.cpp
  clang/test/CodeGenCXX/cfi-mfcall.cpp
  clang/test/CodeGenCXX/type-metadata.cpp
  clang/test/Driver/fsanitize.c
  compiler-rt/lib/ubsan/ubsan_handlers.cc
  compiler-rt/lib/ubsan/ubsan_handlers.h
  compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
  compiler-rt/test/cfi/mfcall.cpp

Index: compiler-rt/test/cfi/mfcall.cpp
===
--- /dev/null
+++ compiler-rt/test/cfi/mfcall.cpp
@@ -0,0 +1,94 @@
+// RUN: %clangxx_cfi -o %t %s
+// RUN: %expect_crash %run %t a
+// RUN: %expect_crash %run %t b
+// RUN: %expect_crash %run %t c
+// RUN: %expect_crash %run %t d
+// RUN: %expect_crash %run %t e
+// RUN: %run %t f
+// RUN: %run %t g
+
+// RUN: %clangxx_cfi_diag -o %t2 %s
+// RUN: %run %t2 a 2>&1 | FileCheck --check-prefix=A %s
+// RUN: %run %t2 b 2>&1 | FileCheck --check-prefix=B %s
+// RUN: %run %t2 c 2>&1 | FileCheck --check-prefix=C %s
+// RUN: %run %t2 d 2>&1 | FileCheck --check-prefix=D %s
+// RUN: %run %t2 e 2>&1 | FileCheck --check-prefix=E %s
+
+#include 
+#include 
+
+struct SBase1 {
+  void b1() {}
+};
+
+struct SBase2 {
+  void b2() {}
+};
+
+struct S : SBase1, SBase2 {
+  void f1() {}
+  int f2() { return 1; }
+  virtual void g1() {}
+  virtual int g2() { return 1; }
+  virtual int g3() { return 1; }
+};
+
+struct T {
+  void f1() {}
+  int f2() { return 2; }
+  virtual void g1() {}
+  virtual int g2() { return 2; }
+  virtual void g3() {}
+};
+
+typedef void (S::*S_void)();
+
+typedef int (S::*S_int)();
+typedef int (T::*T_int)();
+
+template 
+To bitcast(From f) {
+  assert(sizeof(To) == sizeof(From));
+  To t;
+  memcpy(, , sizeof(f));
+  return t;
+}
+
+int main(int argc, char **argv) {
+  S s;
+  T t;
+
+  switch (argv[1][0]) {
+case 'a':
+  // A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual member function call
+  // A: note: S::f1() defined here
+  (s.*bitcast(::f1))();
+  break;
+case 'b':
+  // B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual member function call
+  // B: note: S::f2() defined here
+  (t.*bitcast(::f2))();
+  break;
+case 'c':
+  // C: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual member function call
+  // C: note: vtable is of type 'S'
+  (s.*bitcast(::g1))();
+  break;
+case 'd':
+  // D: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual member function call
+  // D: note: vtable is of type 'T'
+  (reinterpret_cast(t).*::g2)();
+  break;
+case 'e':
+  // E: runtime error: control flow integrity check for type 'void (S::*)()' failed during virtual member function call
+  // E: note: vtable is of type 'S'
+  (s.*bitcast(::g3))();
+  break;
+case 'f':
+  (s.*::b1)();
+  break;
+case 'g':
+  (s.*::b2)();
+  break;
+  }
+}
Index: compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
===
--- compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
+++ compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
@@ -122,7 +122,11 @@
   case CFITCK_UnrelatedCast:
 CheckKindStr = "cast to unrelated type";
 break;
+  case CFITCK_VMFCall:
+CheckKindStr = "virtual member function call";
+break;
   case CFITCK_ICall:
+  case CFITCK_NVMFCall:
 Die();
   }
 
Index: compiler-rt/lib/ubsan/ubsan_handlers.h
===
--- compiler-rt/lib/ubsan/ubsan_handlers.h
+++ compiler-rt/lib/ubsan/ubsan_handlers.h
@@ -181,6 +181,8 @@
   CFITCK_DerivedCast,
   CFITCK_UnrelatedCast,
   CFITCK_ICall,
+  CFITCK_NVMFCall,
+  CFITCK_VMFCall,
 };
 
 struct CFICheckFailData {
Index: compiler-rt/lib/ubsan/ubsan_handlers.cc
===
--- compiler-rt/lib/ubsan/ubsan_handlers.cc
+++ compiler-rt/lib/ubsan/ubsan_handlers.cc
@@ -630,7 +630,7 @@
 
 static void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function,
   ReportOptions Opts) {
-  if (Data->CheckKind != CFITCK_ICall)
+  if (Data->CheckKind != CFITCK_ICall && Data->CheckKind != CFITCK_NVMFCall)
 Die();
 
   SourceLocation Loc = Data->Loc.acquire();
@@ -641,9 +641,12 @@
 
   ScopedReport R(Opts, Loc, ET);
 

r334671 - docs: Add a missing LTO visibility reference.

2018-06-13 Thread Peter Collingbourne via cfe-commits
Author: pcc
Date: Wed Jun 13 16:21:02 2018
New Revision: 334671

URL: http://llvm.org/viewvc/llvm-project?rev=334671=rev
Log:
docs: Add a missing LTO visibility reference.

Modified:
cfe/trunk/docs/ControlFlowIntegrity.rst

Modified: cfe/trunk/docs/ControlFlowIntegrity.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ControlFlowIntegrity.rst?rev=334671=334670=334671=diff
==
--- cfe/trunk/docs/ControlFlowIntegrity.rst (original)
+++ cfe/trunk/docs/ControlFlowIntegrity.rst Wed Jun 13 16:21:02 2018
@@ -104,10 +104,11 @@ dynamic type; that is, the dynamic type
 derived class of the static type of the object used to make the call.
 This CFI scheme can be enabled on its own using ``-fsanitize=cfi-vcall``.
 
-For this scheme to work, all translation units containing the definition of
-a virtual member function (whether inline or not), other than members of
-:ref:`blacklisted ` types, must be compiled with ``-flto``
-or ``-flto=thin`` enabled and be statically linked into the program.
+For this scheme to work, all translation units containing the definition
+of a virtual member function (whether inline or not), other than members
+of :ref:`blacklisted ` types or types with public :doc:`LTO
+visibility `, must be compiled with ``-flto`` or ``-flto=thin``
+enabled and be statically linked into the program.
 
 Performance
 ---


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r334669 - docs: Correct some misstatements in the control flow integrity docs.

2018-06-13 Thread Peter Collingbourne via cfe-commits
Author: pcc
Date: Wed Jun 13 16:18:26 2018
New Revision: 334669

URL: http://llvm.org/viewvc/llvm-project?rev=334669=rev
Log:
docs: Correct some misstatements in the control flow integrity docs.

These were true at one point but haven't been true for a long time.

Modified:
cfe/trunk/docs/ControlFlowIntegrity.rst

Modified: cfe/trunk/docs/ControlFlowIntegrity.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ControlFlowIntegrity.rst?rev=334669=334668=334669=diff
==
--- cfe/trunk/docs/ControlFlowIntegrity.rst (original)
+++ cfe/trunk/docs/ControlFlowIntegrity.rst Wed Jun 13 16:18:26 2018
@@ -104,10 +104,10 @@ dynamic type; that is, the dynamic type
 derived class of the static type of the object used to make the call.
 This CFI scheme can be enabled on its own using ``-fsanitize=cfi-vcall``.
 
-For this scheme to work, all translation units containing the definition
-of a virtual member function (whether inline or not), other than members
-of :ref:`blacklisted ` types, must be compiled with
-``-fsanitize=cfi-vcall`` enabled and be statically linked into the program.
+For this scheme to work, all translation units containing the definition of
+a virtual member function (whether inline or not), other than members of
+:ref:`blacklisted ` types, must be compiled with ``-flto``
+or ``-flto=thin`` enabled and be statically linked into the program.
 
 Performance
 ---
@@ -152,9 +152,9 @@ functions may be :ref:`blacklisted ` types, must be compiled with
-``-fsanitize=cfi-derived-cast`` or ``-fsanitize=cfi-unrelated-cast`` enabled
-and be statically linked into the program.
+of :ref:`blacklisted ` types or types with public :doc:`LTO
+visibility `, must be compiled with ``-flto`` or ``-flto=thin``
+enabled and be statically linked into the program.
 
 Non-Virtual Member Function Call Checking
 =
@@ -168,8 +168,9 @@ polymorphic class type.  This CFI scheme
 
 For this scheme to work, all translation units containing the definition
 of a virtual member function (whether inline or not), other than members
-of :ref:`blacklisted ` types, must be compiled with
-``-fsanitize=cfi-nvcall`` enabled and be statically linked into the program.
+of :ref:`blacklisted ` types or types with public :doc:`LTO
+visibility `, must be compiled with ``-flto`` or ``-flto=thin``
+enabled and be statically linked into the program.
 
 .. _cfi-strictness:
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48106: implemented proto to llvm

2018-06-13 Thread Matt Morehouse via Phabricator via cfe-commits
morehouse added a comment.

In https://reviews.llvm.org/D48106#1131625, @emmettneyman wrote:

> I wanted to implement the proto_to_llvm converter before the fuzz target.


The fuzz target should make testing your converter way easier.  I'd recommend 
adding it to this patch so that you're less likely to need a bug-fixing patch 
later.




Comment at: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp:32
+// Counter variable to generate new LLVM IR variable names and wrapper function
+int ctr = 0;
+std::string get_var() {

You can hide this as a static int inside `get_var`.



Comment at: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp:46
+   + "store i32 " + val + ", i32* " + alloca_var + "\n"
+   + load_var + " = load i32, i32* " + alloca_var + "\n";
+  return std::make_pair(insns, load_var);

What's the point of storing then loading the value?  Can you just return `val`?



Comment at: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp:49
+}
+std::pair  VarRefToString(const VarRef ) {
+  std::string arr;

Returning a pair can be confusing (which element is which?).  I'd suggest 
passing `os` to these functions, writing the instructions to `os`, and then 
returning just the result variable.



Comment at: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp:120
+op = "add";
+break;
+  }

If all these cases are the same, we can simplify the code to
```
case BinaryOp::EQ:
case BinaryOp::NE:
...
op = "add";
break;
```



Comment at: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp:129
+}
+std::string AssignmentStatementToString(const AssignmentStatement ) {
+  std::pair  ref = VarRefToString(x.varref());

If `AssignmentStatementToString` has no extra return value, I think its more 
concise to just keep the `operator<<` overload.  (Same for below functions)


Repository:
  rC Clang

https://reviews.llvm.org/D48106



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48027: [analyzer] Improve `CallDescription` to handle c++ method.

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added inline comments.



Comment at: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp:32
  check::PostCall> {
-  CallDescription CStrFn;
+  const llvm::SmallVector CStrFnFamily = {
+{"std::basic_string::c_str"}, {"std::basic_string::c_str"},

xazax.hun wrote:
> I am not sure if this is the right solution in case of this check. We should 
> track `c_str` calls regardless of what the template parameter is, so 
> supporting any instantiation of `basic_string` is desired. This might not be 
> the case, however, for other checks. 
> 
> If we think it is more likely we do not care about the template arguments, 
> maybe a separate API could be used, where we pass the qualified name of the 
> class separately without the template arguments.
> Alternatively, we could use matches name so the users could use regexps.
> 
> At this point I also wonder what isCalled API gives us compared to matchers? 
> Maybe it is more convenient to use than calling a `match`. Also, isCalled API 
> has an IdentifierInfo cached which could be used for relatively efficient 
> checks.
> 
> @NoQ what do you think?
> 
> 
I agree that it's better to match the chain of classes and namespaces (in as 
much detail as the user cares to provide) and discard template parameters.

For example, i wish that a `CallDescription` that's defined as `{"std", 
"basic_string", "c_str"}` would be able to match both `std::string::c_str()` 
and `std::__1::string::c_str()`.


Repository:
  rC Clang

https://reviews.llvm.org/D48027



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48098: clang-format-diff: Switch to python3 by default, support python 2.7

2018-06-13 Thread Marco Falke via Phabricator via cfe-commits
MarcoFalke updated this revision to Diff 151260.
MarcoFalke edited the summary of this revision.

https://reviews.llvm.org/D48098

Files:
  tools/clang-format/clang-format-diff.py


Index: tools/clang-format/clang-format-diff.py
===
--- tools/clang-format/clang-format-diff.py
+++ tools/clang-format/clang-format-diff.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 #===- clang-format-diff.py - ClangFormat Diff Reformatter *- python 
-*--===#
 #
@@ -25,10 +25,12 @@
 import argparse
 import difflib
 import re
-import string
 import subprocess
-import StringIO
 import sys
+try:
+  from StringIO import StringIO
+except ImportError:
+   from io import StringIO
 
 
 def main():
@@ -84,14 +86,14 @@
 line_count = int(match.group(3))
   if line_count == 0:
 continue
-  end_line = start_line + line_count - 1;
+  end_line = start_line + line_count - 1
   lines_by_file.setdefault(filename, []).extend(
   ['-lines', str(start_line) + ':' + str(end_line)])
 
   # Reformat files containing changes in place.
-  for filename, lines in lines_by_file.iteritems():
+  for filename, lines in lines_by_file.items():
 if args.i and args.verbose:
-  print 'Formatting', filename
+  print('Formatting {}'.format(filename))
 command = [args.binary, filename]
 if args.i:
   command.append('-i')
@@ -100,20 +102,23 @@
 command.extend(lines)
 if args.style:
   command.extend(['-style', args.style])
-p = subprocess.Popen(command, stdout=subprocess.PIPE,
- stderr=None, stdin=subprocess.PIPE)
+p = subprocess.Popen(command,
+ stdout=subprocess.PIPE,
+ stderr=None,
+ stdin=subprocess.PIPE,
+ universal_newlines=True)
 stdout, stderr = p.communicate()
 if p.returncode != 0:
-  sys.exit(p.returncode);
+  sys.exit(p.returncode)
 
 if not args.i:
   with open(filename) as f:
 code = f.readlines()
-  formatted_code = StringIO.StringIO(stdout).readlines()
+  formatted_code = StringIO(stdout).readlines()
   diff = difflib.unified_diff(code, formatted_code,
   filename, filename,
   '(before formatting)', '(after formatting)')
-  diff_string = string.join(diff, '')
+  diff_string = ''.join(diff)
   if len(diff_string) > 0:
 sys.stdout.write(diff_string)
 


Index: tools/clang-format/clang-format-diff.py
===
--- tools/clang-format/clang-format-diff.py
+++ tools/clang-format/clang-format-diff.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 #===- clang-format-diff.py - ClangFormat Diff Reformatter *- python -*--===#
 #
@@ -25,10 +25,12 @@
 import argparse
 import difflib
 import re
-import string
 import subprocess
-import StringIO
 import sys
+try:
+  from StringIO import StringIO
+except ImportError:
+   from io import StringIO
 
 
 def main():
@@ -84,14 +86,14 @@
 line_count = int(match.group(3))
   if line_count == 0:
 continue
-  end_line = start_line + line_count - 1;
+  end_line = start_line + line_count - 1
   lines_by_file.setdefault(filename, []).extend(
   ['-lines', str(start_line) + ':' + str(end_line)])
 
   # Reformat files containing changes in place.
-  for filename, lines in lines_by_file.iteritems():
+  for filename, lines in lines_by_file.items():
 if args.i and args.verbose:
-  print 'Formatting', filename
+  print('Formatting {}'.format(filename))
 command = [args.binary, filename]
 if args.i:
   command.append('-i')
@@ -100,20 +102,23 @@
 command.extend(lines)
 if args.style:
   command.extend(['-style', args.style])
-p = subprocess.Popen(command, stdout=subprocess.PIPE,
- stderr=None, stdin=subprocess.PIPE)
+p = subprocess.Popen(command,
+ stdout=subprocess.PIPE,
+ stderr=None,
+ stdin=subprocess.PIPE,
+ universal_newlines=True)
 stdout, stderr = p.communicate()
 if p.returncode != 0:
-  sys.exit(p.returncode);
+  sys.exit(p.returncode)
 
 if not args.i:
   with open(filename) as f:
 code = f.readlines()
-  formatted_code = StringIO.StringIO(stdout).readlines()
+  formatted_code = StringIO(stdout).readlines()
   diff = difflib.unified_diff(code, formatted_code,
   filename, filename,
   '(before formatting)', '(after formatting)')
-  diff_string = string.join(diff, '')
+  diff_string = ''.join(diff)
   if len(diff_string) > 0:
 sys.stdout.write(diff_string)
 
___

[PATCH] D47554: [analyzer] Check for dead/impossible status checks

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

For now the tests that i proposed may in fact accidentally work because as far 
as i understand you're updating the "variable contains a value returned by 
operator new" flag when you encounter assignment operators. The real problems 
will arise when the order of the assignments in the AST doesn't correspond to 
the order of assignments during program execution.

So one more test i'd like to have is:

  int *m = new int;
  while (true) {
if (m == nullptr) { ... } // no-warning
m = nullptr;
  }


Repository:
  rC Clang

https://reviews.llvm.org/D47554



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47554: [analyzer] Check for dead/impossible status checks

2018-06-13 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

Thanks for adding me!

Hmm, i think a matcher-based solution would be pretty limited. This is 
definitely your typical all-path data-flow problem because you want to make 
sure that you're looking at the //last// assignment to the variable.

For example:

  int *m = new int;
  m = nullptr;
  if (m == nullptr) { ... } // no-warning

but

  int *m = nullptr;
  m = new int;
  if (m == nullptr) { ... } // expected-warning{{}}

You might be able to fix false positives by adding a condition that the 
variable is not re-assigned within the function (with the help of assignment 
operator or due to taking a non-constant reference to it, etc). But you'll end 
up with a checker that finds a lot less bugs than a full-featured data flow 
analysis could have found. There's a canonical implementation of "the variable 
is not modified" check via ASTMatchers in `LoopUnrolling.cpp`.

If you'll ever want to find a full-featured data flow check, i'm not sure but 
you might be able to re-use `LiveVariables` analysis (the non-`Relaxed` one) to 
find the last assignment, and in this case you won't have to write data flow 
analysis yourself. `DeadStores` checker has an example of that.


Repository:
  rC Clang

https://reviews.llvm.org/D47554



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48098: clang-format-diff: Switch to python3 by default, support python 2.7

2018-06-13 Thread Marco Falke via Phabricator via cfe-commits
MarcoFalke added a comment.

>   why is this switch necessary?

It is not necessary, but would be nice if the script run on python3 as well (as 
opposed to only python2, which is going to be deprecated 
https://pythonclock.org/)

>   what's expected to be supported with it?

I'd assume python2.7 (which is the only supported python2) and everything from 
python3.4 and upward.

>   how do I test it?

The clang-format-diff.py is a wrapper around clang-format, to format only a 
diff. You can get any diff, e.g. the last ten commits to the master branch:

  git diff HEAD~10 -U0 | python2 ./tools/clang-format/clang-format-diff.py

(You might have to pass `-p1`)

Then test that the following options work with both python2 and python3:

  -i -v  # flags
  -regex # could be -regex '.*\.h'
  -iregex # could be -iregex '.*\.H'




https://reviews.llvm.org/D48098



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42043: c-index: CXString: fix MSAN read-past-end bug

2018-06-13 Thread Vitaly Buka via Phabricator via cfe-commits
vitalybuka added a comment.

Is this stale?


Repository:
  rC Clang

https://reviews.llvm.org/D42043



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48036: [CUDA] Make min/max shims host+device.

2018-06-13 Thread Justin Lebar via Phabricator via cfe-commits
jlebar added a comment.

In https://reviews.llvm.org/D48036#1131279, @tra wrote:

> Ack.


Patches sent (see dependency chain in phab).


https://reviews.llvm.org/D48036



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48152: [CUDA] Add tests that, in C++14 mode, min/max are constexpr.

2018-06-13 Thread Justin Lebar via Phabricator via cfe-commits
jlebar created this revision.
jlebar added reviewers: rsmith, tra.
Herald added a subscriber: llvm-commits.

Repository:
  rT test-suite

https://reviews.llvm.org/D48152

Files:
  External/CUDA/algorithm.cu


Index: External/CUDA/algorithm.cu
===
--- External/CUDA/algorithm.cu
+++ External/CUDA/algorithm.cu
@@ -42,6 +42,8 @@
   assert(std::minmax(1, 0).second == 1);
   assert(std::minmax({0, 10, -10, 100}, std::less()).first == -10);
   assert(std::minmax({0, 10, -10, 100}, std::less()).second == 100);
+  constexpr auto min = std::min(1, 2);
+  constexpr auto max = std::max(1, 2);
 #endif
 }
 
@@ -56,6 +58,8 @@
   assert(std::minmax(1, 0).second == 1);
   assert(std::minmax({0, 10, -10, 100}, std::less()).first == -10);
   assert(std::minmax({0, 10, -10, 100}, std::less()).second == 100);
+  constexpr auto min = std::min(1, 2);
+  constexpr auto max = std::max(1, 2);
 #endif
 }
 


Index: External/CUDA/algorithm.cu
===
--- External/CUDA/algorithm.cu
+++ External/CUDA/algorithm.cu
@@ -42,6 +42,8 @@
   assert(std::minmax(1, 0).second == 1);
   assert(std::minmax({0, 10, -10, 100}, std::less()).first == -10);
   assert(std::minmax({0, 10, -10, 100}, std::less()).second == 100);
+  constexpr auto min = std::min(1, 2);
+  constexpr auto max = std::max(1, 2);
 #endif
 }
 
@@ -56,6 +58,8 @@
   assert(std::minmax(1, 0).second == 1);
   assert(std::minmax({0, 10, -10, 100}, std::less()).first == -10);
   assert(std::minmax({0, 10, -10, 100}, std::less()).second == 100);
+  constexpr auto min = std::min(1, 2);
+  constexpr auto max = std::max(1, 2);
 #endif
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48151: [CUDA] Make __host__/__device__ min/max overloads constexpr in C++14.

2018-06-13 Thread Justin Lebar via Phabricator via cfe-commits
jlebar created this revision.
jlebar added reviewers: rsmith, tra.
Herald added a subscriber: sanjoy.

Tests in a separate change to the test-suite.


https://reviews.llvm.org/D48151

Files:
  clang/lib/Headers/cuda_wrappers/algorithm


Index: clang/lib/Headers/cuda_wrappers/algorithm
===
--- clang/lib/Headers/cuda_wrappers/algorithm
+++ clang/lib/Headers/cuda_wrappers/algorithm
@@ -67,34 +67,43 @@
 #endif
 #endif
 
+#pragma push_macro("_CPP14_CONSTEXPR")
+#if __cplusplus >= 201402L
+#define _CPP14_CONSTEXPR constexpr
+#else
+#define _CPP14_CONSTEXPR
+#endif
+
 template 
 __attribute__((enable_if(true, "")))
-inline __host__ __device__ const __T &
+inline _CPP14_CONSTEXPR __host__ __device__ const __T &
 max(const __T &__a, const __T &__b, __Cmp __cmp) {
   return __cmp(__a, __b) ? __b : __a;
 }
 
 template 
 __attribute__((enable_if(true, "")))
-inline __host__ __device__ const __T &
+inline _CPP14_CONSTEXPR __host__ __device__ const __T &
 max(const __T &__a, const __T &__b) {
   return __a < __b ? __b : __a;
 }
 
 template 
 __attribute__((enable_if(true, "")))
-inline __host__ __device__ const __T &
+inline _CPP14_CONSTEXPR __host__ __device__ const __T &
 min(const __T &__a, const __T &__b, __Cmp __cmp) {
   return __cmp(__b, __a) ? __b : __a;
 }
 
 template 
 __attribute__((enable_if(true, "")))
-inline __host__ __device__ const __T &
+inline _CPP14_CONSTEXPR __host__ __device__ const __T &
 min(const __T &__a, const __T &__b) {
   return __a < __b ? __a : __b;
 }
 
+#pragma pop_macro("_CPP14_CONSTEXPR")
+
 #ifdef _LIBCPP_END_NAMESPACE_STD
 _LIBCPP_END_NAMESPACE_STD
 #else


Index: clang/lib/Headers/cuda_wrappers/algorithm
===
--- clang/lib/Headers/cuda_wrappers/algorithm
+++ clang/lib/Headers/cuda_wrappers/algorithm
@@ -67,34 +67,43 @@
 #endif
 #endif
 
+#pragma push_macro("_CPP14_CONSTEXPR")
+#if __cplusplus >= 201402L
+#define _CPP14_CONSTEXPR constexpr
+#else
+#define _CPP14_CONSTEXPR
+#endif
+
 template 
 __attribute__((enable_if(true, "")))
-inline __host__ __device__ const __T &
+inline _CPP14_CONSTEXPR __host__ __device__ const __T &
 max(const __T &__a, const __T &__b, __Cmp __cmp) {
   return __cmp(__a, __b) ? __b : __a;
 }
 
 template 
 __attribute__((enable_if(true, "")))
-inline __host__ __device__ const __T &
+inline _CPP14_CONSTEXPR __host__ __device__ const __T &
 max(const __T &__a, const __T &__b) {
   return __a < __b ? __b : __a;
 }
 
 template 
 __attribute__((enable_if(true, "")))
-inline __host__ __device__ const __T &
+inline _CPP14_CONSTEXPR __host__ __device__ const __T &
 min(const __T &__a, const __T &__b, __Cmp __cmp) {
   return __cmp(__b, __a) ? __b : __a;
 }
 
 template 
 __attribute__((enable_if(true, "")))
-inline __host__ __device__ const __T &
+inline _CPP14_CONSTEXPR __host__ __device__ const __T &
 min(const __T &__a, const __T &__b) {
   return __a < __b ? __a : __b;
 }
 
+#pragma pop_macro("_CPP14_CONSTEXPR")
+
 #ifdef _LIBCPP_END_NAMESPACE_STD
 _LIBCPP_END_NAMESPACE_STD
 #else
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48100: Append new attributes to the end of an AttributeList.

2018-06-13 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur marked 4 inline comments as done.
Meinersbur added inline comments.



Comment at: lib/AST/ItaniumMangle.cpp:710-711
 Out << "Ua9enable_ifI";
 // FIXME: specific_attr_iterator iterates in reverse order. Fix that and 
use
 // it here.
+for (AttrVec::const_iterator I = FD->getAttrs().begin(),

Will remove this FIXME in the next update.


Repository:
  rC Clang

https://reviews.llvm.org/D48100



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38680: [libunwind] Fix handling of DW_CFA_GNU_args_size

2018-06-13 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

In https://reviews.llvm.org/D38680#1123018, @joerg wrote:

> After a careful review of newer GCC / libgcc and the assembler annotations 
> from LLVM, I have come to the following conclusions:
>
> (1) The semantics have been somewhat changed by GCC in recent years. There is 
> no actual specification, so we have to go by what behavior actually makes 
> sense.
>  (2) The primary motivation is still that the DW_CFA_GNU_args_size is a 
> call-site specific annotation. It is expected to be applied when the IP is 
> moved by the personality routine to compensate for the call site specific 
> (temporary) adjustment.


Right.

> (3) It is not clear with plain unw_set_ip outside the scope of the Itanium EH 
> handling should have this behavior, so it might need to be split into an 
> internal routine.

I don't know enough about this code to really respond to this.

> (4) LLVM does not produce correct CFA annotation for stdcall and similar 
> cases where the callee removes additional stack space.

Here's what we generate for that case today: https://godbolt.org/g/33cNJy
The important part is:

  .cfi_escape 0x2e, 0x0c
  pushl   $3
  .cfi_adjust_cfa_offset 4
  pushl   $2
  .cfi_adjust_cfa_offset 4
  pushl   $1
  .cfi_adjust_cfa_offset 4
  calll   __Z13may_throw_stdiii@12
  .cfi_adjust_cfa_offset -12

Are you saying that the runtime will calculate the wrong CFA because it will 
include the `.cfi_adjust_cfa_offset -12`? As in, adding a nop after the call 
would fix the glitch? If so, I think the right thing to do would be to fix 
libunwind to use return_address - 1 when unwinding.


https://reviews.llvm.org/D38680



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47401: [X86] Rewrite the max and min reduction intrinsics to make better use of other functions and to reduce width to 256 and 128 bits were possible.

2018-06-13 Thread Craig Topper via Phabricator via cfe-commits
craig.topper added a comment.

Ping


Repository:
  rL LLVM

https://reviews.llvm.org/D47401



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48134: [CodeGen] make nan builtins pure rather than const (PR37778)

2018-06-13 Thread Sanjay Patel via Phabricator via cfe-commits
spatel added a comment.

In https://reviews.llvm.org/D48134#1131626, @rsmith wrote:

> Can we mark these as `argmemonly`?


I wasn't aware of that one, but it sounds accurate for nan() and friends:

  argmemonly
This attribute indicates that the only memory accesses inside function are 
loads and stores from objects pointed to by its pointer-typed arguments, with 
arbitrary offsets. Or in other words, all memory operations in the function can 
refer to memory only using pointers based on its function arguments. Note that 
argmemonly can be used together with readonly attribute in order to specify 
that function reads only from its arguments.

But as Roman noted, we're going to have to update the list of possibilities to 
include "NoAliasAttr"? And might need to adjust the logic where that gets 
mapped to the LLVM attr.


Repository:
  rL LLVM

https://reviews.llvm.org/D48134



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45679: [clang-tidy] Add ExprMutationAnalyzer, that analyzes whether an expression is mutated within a statement.

2018-06-13 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang added a comment.

In https://reviews.llvm.org/D45679#1131115, @aaron.ballman wrote:

> I had to revert due to failing tests. The revert was done in r334606 and this 
> is an example of a failing bot: 
> http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast/builds/31500


Apparently I can't include  in unit test cases (somehow that works on 
my machine :p)
Changed to just forward declare std::type_info instead.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D45679



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45679: [clang-tidy] Add ExprMutationAnalyzer, that analyzes whether an expression is mutated within a statement.

2018-06-13 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang updated this revision to Diff 151245.
shuaiwang added a comment.

Add include  for std::isspace() (thanks aaron.ballman!)


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D45679

Files:
  clang-tidy/utils/CMakeLists.txt
  clang-tidy/utils/ExprMutationAnalyzer.cpp
  clang-tidy/utils/ExprMutationAnalyzer.h
  unittests/clang-tidy/CMakeLists.txt
  unittests/clang-tidy/ExprMutationAnalyzerTest.cpp

Index: unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
===
--- /dev/null
+++ unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
@@ -0,0 +1,609 @@
+//===-- ExprMutationAnalyzerTest.cpp - clang-tidy -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "../clang-tidy/utils/ExprMutationAnalyzer.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include 
+
+namespace clang {
+namespace tidy {
+namespace test {
+
+using namespace clang::ast_matchers;
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+using ::testing::ResultOf;
+using ::testing::StartsWith;
+using ::testing::Values;
+
+namespace {
+
+using ExprMatcher = internal::Matcher;
+using StmtMatcher = internal::Matcher;
+
+ExprMatcher declRefTo(StringRef Name) {
+  return declRefExpr(to(namedDecl(hasName(Name;
+}
+
+StmtMatcher withEnclosingCompound(ExprMatcher Matcher) {
+  return expr(Matcher, hasAncestor(compoundStmt().bind("stmt"))).bind("expr");
+}
+
+bool isMutated(const SmallVectorImpl , ASTUnit *AST) {
+  const auto *const S = selectFirst("stmt", Results);
+  const auto *const E = selectFirst("expr", Results);
+  return utils::ExprMutationAnalyzer(S, >getASTContext()).isMutated(E);
+}
+
+SmallVector
+mutatedBy(const SmallVectorImpl , ASTUnit *AST) {
+  const auto *const S = selectFirst("stmt", Results);
+  SmallVector Chain;
+  utils::ExprMutationAnalyzer Analyzer(S, >getASTContext());
+  for (const auto *E = selectFirst("expr", Results); E != nullptr;) {
+const Stmt *By = Analyzer.findMutation(E);
+std::string buffer;
+llvm::raw_string_ostream stream(buffer);
+By->printPretty(stream, nullptr, AST->getASTContext().getPrintingPolicy());
+Chain.push_back(StringRef(stream.str()).trim().str());
+E = dyn_cast(By);
+  }
+  return Chain;
+}
+
+std::string removeSpace(std::string s) {
+  s.erase(std::remove_if(s.begin(), s.end(),
+ [](char c) { return std::isspace(c); }),
+  s.end());
+  return s;
+}
+
+} // namespace
+
+TEST(ExprMutationAnalyzerTest, Trivial) {
+  const auto AST = tooling::buildASTFromCode("void f() { int x; x; }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+}
+
+class AssignmentTest : public ::testing::TestWithParam {};
+
+TEST_P(AssignmentTest, AssignmentModifies) {
+  const std::string ModExpr = "x " + GetParam() + " 10";
+  const auto AST =
+  tooling::buildASTFromCode("void f() { int x; " + ModExpr + "; }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre(ModExpr));
+}
+
+INSTANTIATE_TEST_CASE_P(AllAssignmentOperators, AssignmentTest,
+Values("=", "+=", "-=", "*=", "/=", "%=", "&=", "|=",
+   "^=", "<<=", ">>="), );
+
+class IncDecTest : public ::testing::TestWithParam {};
+
+TEST_P(IncDecTest, IncDecModifies) {
+  const std::string ModExpr = GetParam();
+  const auto AST =
+  tooling::buildASTFromCode("void f() { int x; " + ModExpr + "; }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre(ModExpr));
+}
+
+INSTANTIATE_TEST_CASE_P(AllIncDecOperators, IncDecTest,
+Values("++x", "--x", "x++", "x--"), );
+
+TEST(ExprMutationAnalyzerTest, NonConstMemberFunc) {
+  const auto AST = tooling::buildASTFromCode(
+  "void f() { struct Foo { void mf(); }; Foo x; x.mf(); }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()"));
+}
+
+TEST(ExprMutationAnalyzerTest, ConstMemberFunc) {
+  const auto AST = tooling::buildASTFromCode(
+  "void f() { struct Foo { void mf() const; }; Foo x; x.mf(); }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, NonConstOperator) {
+ 

[PATCH] D48134: [CodeGen] make nan builtins pure rather than const (PR37778)

2018-06-13 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.

In https://reviews.llvm.org/D48134#1131626, @rsmith wrote:

> Can we mark these as `argmemonly`?


Header comment in `include/clang/Basic/Builtins.def` does not list that as a 
possibility.


Repository:
  rL LLVM

https://reviews.llvm.org/D48134



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45679: [clang-tidy] Add ExprMutationAnalyzer, that analyzes whether an expression is mutated within a statement.

2018-06-13 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang updated this revision to Diff 151244.
shuaiwang added a comment.

Don't include  in unit tests, should fix the test failures.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D45679

Files:
  clang-tidy/utils/CMakeLists.txt
  clang-tidy/utils/ExprMutationAnalyzer.cpp
  clang-tidy/utils/ExprMutationAnalyzer.h
  unittests/clang-tidy/CMakeLists.txt
  unittests/clang-tidy/ExprMutationAnalyzerTest.cpp

Index: unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
===
--- /dev/null
+++ unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
@@ -0,0 +1,608 @@
+//===-- ExprMutationAnalyzerTest.cpp - clang-tidy -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "../clang-tidy/utils/ExprMutationAnalyzer.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace tidy {
+namespace test {
+
+using namespace clang::ast_matchers;
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+using ::testing::ResultOf;
+using ::testing::StartsWith;
+using ::testing::Values;
+
+namespace {
+
+using ExprMatcher = internal::Matcher;
+using StmtMatcher = internal::Matcher;
+
+ExprMatcher declRefTo(StringRef Name) {
+  return declRefExpr(to(namedDecl(hasName(Name;
+}
+
+StmtMatcher withEnclosingCompound(ExprMatcher Matcher) {
+  return expr(Matcher, hasAncestor(compoundStmt().bind("stmt"))).bind("expr");
+}
+
+bool isMutated(const SmallVectorImpl , ASTUnit *AST) {
+  const auto *const S = selectFirst("stmt", Results);
+  const auto *const E = selectFirst("expr", Results);
+  return utils::ExprMutationAnalyzer(S, >getASTContext()).isMutated(E);
+}
+
+SmallVector
+mutatedBy(const SmallVectorImpl , ASTUnit *AST) {
+  const auto *const S = selectFirst("stmt", Results);
+  SmallVector Chain;
+  utils::ExprMutationAnalyzer Analyzer(S, >getASTContext());
+  for (const auto *E = selectFirst("expr", Results); E != nullptr;) {
+const Stmt *By = Analyzer.findMutation(E);
+std::string buffer;
+llvm::raw_string_ostream stream(buffer);
+By->printPretty(stream, nullptr, AST->getASTContext().getPrintingPolicy());
+Chain.push_back(StringRef(stream.str()).trim().str());
+E = dyn_cast(By);
+  }
+  return Chain;
+}
+
+std::string removeSpace(std::string s) {
+  s.erase(std::remove_if(s.begin(), s.end(),
+ [](char c) { return std::isspace(c); }),
+  s.end());
+  return s;
+}
+
+} // namespace
+
+TEST(ExprMutationAnalyzerTest, Trivial) {
+  const auto AST = tooling::buildASTFromCode("void f() { int x; x; }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+}
+
+class AssignmentTest : public ::testing::TestWithParam {};
+
+TEST_P(AssignmentTest, AssignmentModifies) {
+  const std::string ModExpr = "x " + GetParam() + " 10";
+  const auto AST =
+  tooling::buildASTFromCode("void f() { int x; " + ModExpr + "; }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre(ModExpr));
+}
+
+INSTANTIATE_TEST_CASE_P(AllAssignmentOperators, AssignmentTest,
+Values("=", "+=", "-=", "*=", "/=", "%=", "&=", "|=",
+   "^=", "<<=", ">>="), );
+
+class IncDecTest : public ::testing::TestWithParam {};
+
+TEST_P(IncDecTest, IncDecModifies) {
+  const std::string ModExpr = GetParam();
+  const auto AST =
+  tooling::buildASTFromCode("void f() { int x; " + ModExpr + "; }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre(ModExpr));
+}
+
+INSTANTIATE_TEST_CASE_P(AllIncDecOperators, IncDecTest,
+Values("++x", "--x", "x++", "x--"), );
+
+TEST(ExprMutationAnalyzerTest, NonConstMemberFunc) {
+  const auto AST = tooling::buildASTFromCode(
+  "void f() { struct Foo { void mf(); }; Foo x; x.mf(); }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()"));
+}
+
+TEST(ExprMutationAnalyzerTest, ConstMemberFunc) {
+  const auto AST = tooling::buildASTFromCode(
+  "void f() { struct Foo { void mf() const; }; Foo x; x.mf(); }");
+  const auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, NonConstOperator) {
+  const 

r334652 - Simplify test from r334650

2018-06-13 Thread Erich Keane via cfe-commits
Author: erichkeane
Date: Wed Jun 13 13:47:12 2018
New Revision: 334652

URL: http://llvm.org/viewvc/llvm-project?rev=334652=rev
Log:
Simplify test from r334650

No reason to have the 'bool' as an intermediary value,
simply use the fact that curley braces enforce eval order.

Modified:
cfe/trunk/test/SemaCXX/builtins-overflow.cpp

Modified: cfe/trunk/test/SemaCXX/builtins-overflow.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtins-overflow.cpp?rev=334652=334651=334652=diff
==
--- cfe/trunk/test/SemaCXX/builtins-overflow.cpp (original)
+++ cfe/trunk/test/SemaCXX/builtins-overflow.cpp Wed Jun 13 13:47:12 2018
@@ -29,8 +29,7 @@ struct Result {
 template 
 constexpr Result add(LHS &, RHS &) {
   RET sum{};
-  bool b = __builtin_add_overflow(lhs, rhs, );
-  return {b, sum};
+  return {__builtin_add_overflow(lhs, rhs, ), sum};
 }
 
 static_assert(add(static_cast(120), static_cast(10)) == 
Result{false, 130});
@@ -45,8 +44,7 @@ static_assert(add(INT_MIN + 22, -23
 template 
 constexpr Result sub(LHS &, RHS &) {
   RET sum{};
-  bool b = __builtin_sub_overflow(lhs, rhs, );
-  return {b, sum};
+  return {__builtin_sub_overflow(lhs, rhs, ), sum};
 }
 
 static_assert(sub(static_cast(0),static_cast(1)) == 
Result{true, UCHAR_MAX});
@@ -60,8 +58,7 @@ static_assert(sub(INT_MIN + 22, 23)
 template 
 constexpr Result mul(LHS &, RHS &) {
   RET sum{};
-  bool b  = __builtin_mul_overflow(lhs, rhs, );
-  return {b, sum};
+  return {__builtin_mul_overflow(lhs, rhs, ), sum};
 }
 
 static_assert(mul(17,22) == Result{false, 374});
@@ -70,8 +67,7 @@ static_assert(mul(INT_MIN / 22, -23
 
 constexpr Result sadd(int lhs, int rhs) {
   int sum{};
-  bool b = __builtin_sadd_overflow(lhs, rhs, );
-  return {b, sum};
+  return {__builtin_sadd_overflow(lhs, rhs, ), sum};
 }
 
 static_assert(sadd(17,22) == Result{false, 39});
@@ -80,8 +76,7 @@ static_assert(sadd(INT_MIN + 22, -23) ==
 
 constexpr Result ssub(int lhs, int rhs) {
   int sum{};
-  bool b = __builtin_ssub_overflow(lhs, rhs, );
-  return {b, sum};
+  return {__builtin_ssub_overflow(lhs, rhs, ), sum};
 }
 
 static_assert(ssub(17,22) == Result{false, -5});
@@ -90,8 +85,7 @@ static_assert(ssub(INT_MIN + 22, 23) ==
 
 constexpr Result smul(int lhs, int rhs) {
   int sum{};
-  bool b = __builtin_smul_overflow(lhs, rhs, );
-  return {b, sum};
+  return {__builtin_smul_overflow(lhs, rhs, ), sum};
 }
 
 static_assert(smul(17,22) == Result{false, 374});


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48040: Implement constexpr __builtin_*_overflow

2018-06-13 Thread Erich Keane via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL334650: Implement constexpr __builtin_*_overflow (authored 
by erichkeane, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D48040?vs=151151=151241#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D48040

Files:
  cfe/trunk/lib/AST/ExprConstant.cpp
  cfe/trunk/test/SemaCXX/builtins-overflow.cpp

Index: cfe/trunk/lib/AST/ExprConstant.cpp
===
--- cfe/trunk/lib/AST/ExprConstant.cpp
+++ cfe/trunk/lib/AST/ExprConstant.cpp
@@ -8155,6 +8155,124 @@
   case Builtin::BIomp_is_initial_device:
 // We can decide statically which value the runtime would return if called.
 return Success(Info.getLangOpts().OpenMPIsDevice ? 0 : 1, E);
+  case Builtin::BI__builtin_add_overflow:
+  case Builtin::BI__builtin_sub_overflow:
+  case Builtin::BI__builtin_mul_overflow:
+  case Builtin::BI__builtin_sadd_overflow:
+  case Builtin::BI__builtin_uadd_overflow:
+  case Builtin::BI__builtin_uaddl_overflow:
+  case Builtin::BI__builtin_uaddll_overflow:
+  case Builtin::BI__builtin_usub_overflow:
+  case Builtin::BI__builtin_usubl_overflow:
+  case Builtin::BI__builtin_usubll_overflow:
+  case Builtin::BI__builtin_umul_overflow:
+  case Builtin::BI__builtin_umull_overflow:
+  case Builtin::BI__builtin_umulll_overflow:
+  case Builtin::BI__builtin_saddl_overflow:
+  case Builtin::BI__builtin_saddll_overflow:
+  case Builtin::BI__builtin_ssub_overflow:
+  case Builtin::BI__builtin_ssubl_overflow:
+  case Builtin::BI__builtin_ssubll_overflow:
+  case Builtin::BI__builtin_smul_overflow:
+  case Builtin::BI__builtin_smull_overflow:
+  case Builtin::BI__builtin_smulll_overflow: {
+LValue ResultLValue;
+APSInt LHS, RHS;
+
+QualType ResultType = E->getArg(2)->getType()->getPointeeType();
+if (!EvaluateInteger(E->getArg(0), LHS, Info) ||
+!EvaluateInteger(E->getArg(1), RHS, Info) ||
+!EvaluatePointer(E->getArg(2), ResultLValue, Info))
+  return false;
+
+APSInt Result;
+bool DidOverflow = false;
+
+// If the types don't have to match, enlarge all 3 to the largest of them.
+if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
+BuiltinOp == Builtin::BI__builtin_sub_overflow ||
+BuiltinOp == Builtin::BI__builtin_mul_overflow) {
+  bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
+  ResultType->isSignedIntegerOrEnumerationType();
+  bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
+  ResultType->isSignedIntegerOrEnumerationType();
+  uint64_t LHSSize = LHS.getBitWidth();
+  uint64_t RHSSize = RHS.getBitWidth();
+  uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
+  uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
+
+  // Add an additional bit if the signedness isn't uniformly agreed to. We
+  // could do this ONLY if there is a signed and an unsigned that both have
+  // MaxBits, but the code to check that is pretty nasty.  The issue will be
+  // caught in the shrink-to-result later anyway.
+  if (IsSigned && !AllSigned)
+++MaxBits;
+
+  LHS = APSInt(IsSigned ? LHS.sextOrSelf(MaxBits) : LHS.zextOrSelf(MaxBits),
+   !IsSigned);
+  RHS = APSInt(IsSigned ? RHS.sextOrSelf(MaxBits) : RHS.zextOrSelf(MaxBits),
+   !IsSigned);
+  Result = APSInt(MaxBits, !IsSigned);
+}
+
+// Find largest int.
+switch (BuiltinOp) {
+default:
+  llvm_unreachable("Invalid value for BuiltinOp");
+case Builtin::BI__builtin_add_overflow:
+case Builtin::BI__builtin_sadd_overflow:
+case Builtin::BI__builtin_saddl_overflow:
+case Builtin::BI__builtin_saddll_overflow:
+case Builtin::BI__builtin_uadd_overflow:
+case Builtin::BI__builtin_uaddl_overflow:
+case Builtin::BI__builtin_uaddll_overflow:
+  Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
+  : LHS.uadd_ov(RHS, DidOverflow);
+  break;
+case Builtin::BI__builtin_sub_overflow:
+case Builtin::BI__builtin_ssub_overflow:
+case Builtin::BI__builtin_ssubl_overflow:
+case Builtin::BI__builtin_ssubll_overflow:
+case Builtin::BI__builtin_usub_overflow:
+case Builtin::BI__builtin_usubl_overflow:
+case Builtin::BI__builtin_usubll_overflow:
+  Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
+  : LHS.usub_ov(RHS, DidOverflow);
+  break;
+case Builtin::BI__builtin_mul_overflow:
+case Builtin::BI__builtin_smul_overflow:
+case Builtin::BI__builtin_smull_overflow:
+case Builtin::BI__builtin_smulll_overflow:
+case Builtin::BI__builtin_umul_overflow:
+case Builtin::BI__builtin_umull_overflow:
+case Builtin::BI__builtin_umulll_overflow:
+  Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
+  

r334650 - Implement constexpr __builtin_*_overflow

2018-06-13 Thread Erich Keane via cfe-commits
Author: erichkeane
Date: Wed Jun 13 13:43:27 2018
New Revision: 334650

URL: http://llvm.org/viewvc/llvm-project?rev=334650=rev
Log:
Implement constexpr __builtin_*_overflow

As requested here:https://bugs.llvm.org/show_bug.cgi?id=37633
permit the __builtin_*_overflow builtins in constexpr functions.

Differential Revision: https://reviews.llvm.org/D48040

Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/SemaCXX/builtins-overflow.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=334650=334649=334650=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Jun 13 13:43:27 2018
@@ -8155,6 +8155,124 @@ bool IntExprEvaluator::VisitBuiltinCallE
   case Builtin::BIomp_is_initial_device:
 // We can decide statically which value the runtime would return if called.
 return Success(Info.getLangOpts().OpenMPIsDevice ? 0 : 1, E);
+  case Builtin::BI__builtin_add_overflow:
+  case Builtin::BI__builtin_sub_overflow:
+  case Builtin::BI__builtin_mul_overflow:
+  case Builtin::BI__builtin_sadd_overflow:
+  case Builtin::BI__builtin_uadd_overflow:
+  case Builtin::BI__builtin_uaddl_overflow:
+  case Builtin::BI__builtin_uaddll_overflow:
+  case Builtin::BI__builtin_usub_overflow:
+  case Builtin::BI__builtin_usubl_overflow:
+  case Builtin::BI__builtin_usubll_overflow:
+  case Builtin::BI__builtin_umul_overflow:
+  case Builtin::BI__builtin_umull_overflow:
+  case Builtin::BI__builtin_umulll_overflow:
+  case Builtin::BI__builtin_saddl_overflow:
+  case Builtin::BI__builtin_saddll_overflow:
+  case Builtin::BI__builtin_ssub_overflow:
+  case Builtin::BI__builtin_ssubl_overflow:
+  case Builtin::BI__builtin_ssubll_overflow:
+  case Builtin::BI__builtin_smul_overflow:
+  case Builtin::BI__builtin_smull_overflow:
+  case Builtin::BI__builtin_smulll_overflow: {
+LValue ResultLValue;
+APSInt LHS, RHS;
+
+QualType ResultType = E->getArg(2)->getType()->getPointeeType();
+if (!EvaluateInteger(E->getArg(0), LHS, Info) ||
+!EvaluateInteger(E->getArg(1), RHS, Info) ||
+!EvaluatePointer(E->getArg(2), ResultLValue, Info))
+  return false;
+
+APSInt Result;
+bool DidOverflow = false;
+
+// If the types don't have to match, enlarge all 3 to the largest of them.
+if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
+BuiltinOp == Builtin::BI__builtin_sub_overflow ||
+BuiltinOp == Builtin::BI__builtin_mul_overflow) {
+  bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
+  ResultType->isSignedIntegerOrEnumerationType();
+  bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
+  ResultType->isSignedIntegerOrEnumerationType();
+  uint64_t LHSSize = LHS.getBitWidth();
+  uint64_t RHSSize = RHS.getBitWidth();
+  uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
+  uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
+
+  // Add an additional bit if the signedness isn't uniformly agreed to. We
+  // could do this ONLY if there is a signed and an unsigned that both have
+  // MaxBits, but the code to check that is pretty nasty.  The issue will 
be
+  // caught in the shrink-to-result later anyway.
+  if (IsSigned && !AllSigned)
+++MaxBits;
+
+  LHS = APSInt(IsSigned ? LHS.sextOrSelf(MaxBits) : 
LHS.zextOrSelf(MaxBits),
+   !IsSigned);
+  RHS = APSInt(IsSigned ? RHS.sextOrSelf(MaxBits) : 
RHS.zextOrSelf(MaxBits),
+   !IsSigned);
+  Result = APSInt(MaxBits, !IsSigned);
+}
+
+// Find largest int.
+switch (BuiltinOp) {
+default:
+  llvm_unreachable("Invalid value for BuiltinOp");
+case Builtin::BI__builtin_add_overflow:
+case Builtin::BI__builtin_sadd_overflow:
+case Builtin::BI__builtin_saddl_overflow:
+case Builtin::BI__builtin_saddll_overflow:
+case Builtin::BI__builtin_uadd_overflow:
+case Builtin::BI__builtin_uaddl_overflow:
+case Builtin::BI__builtin_uaddll_overflow:
+  Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
+  : LHS.uadd_ov(RHS, DidOverflow);
+  break;
+case Builtin::BI__builtin_sub_overflow:
+case Builtin::BI__builtin_ssub_overflow:
+case Builtin::BI__builtin_ssubl_overflow:
+case Builtin::BI__builtin_ssubll_overflow:
+case Builtin::BI__builtin_usub_overflow:
+case Builtin::BI__builtin_usubl_overflow:
+case Builtin::BI__builtin_usubll_overflow:
+  Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
+  : LHS.usub_ov(RHS, DidOverflow);
+  break;
+case Builtin::BI__builtin_mul_overflow:
+case Builtin::BI__builtin_smul_overflow:
+case Builtin::BI__builtin_smull_overflow:
+case Builtin::BI__builtin_smulll_overflow:
+  

[PATCH] D48106: implemented proto to llvm

2018-06-13 Thread Emmett Neyman via Phabricator via cfe-commits
emmettneyman updated this revision to Diff 151240.
emmettneyman added a comment.

- removed typo in emitted llvm insn


Repository:
  rC Clang

https://reviews.llvm.org/D48106

Files:
  tools/clang-fuzzer/CMakeLists.txt
  tools/clang-fuzzer/cxx_loop_proto.proto
  tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp
  tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx_main.cpp
  tools/clang-fuzzer/proto-to-llvm/CMakeLists.txt
  tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
  tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h
  tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp

Index: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp
===
--- tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp
+++ tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp
@@ -1,32 +1,31 @@
-//==-- loop_proto_to_cxx_main.cpp - Driver for protobuf-C++ conversion -==//
+//==-- loop_proto_to_llvm_main.cpp - Driver for protobuf-LLVM conversion==//
 //
 // The LLVM Compiler Infrastructure
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===--===//
 //
-// Implements a simple driver to print a C++ program from a protobuf with loops.
+// Implements a simple driver to print a LLVM program from a protobuf with loops
 //
 //===--===//
 
-// This is a copy and will be updated later to introduce changes
 
 #include 
 #include 
 #include 
 #include 
 
-#include "proto_to_cxx.h"
+#include "loop_proto_to_llvm.h"
 
 int main(int argc, char **argv) {
   for (int i = 1; i < argc; i++) {
 std::fstream in(argv[i]);
 std::string str((std::istreambuf_iterator(in)),
 std::istreambuf_iterator());
-std::cout << "// " << argv[i] << std::endl;
-std::cout << clang_fuzzer::LoopProtoToCxx(
+std::cout << ";; " << argv[i] << std::endl;
+std::cout << clang_fuzzer::LoopProtoToLLVM(
 reinterpret_cast(str.data()), str.size());
   }
 }
Index: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h
===
--- /dev/null
+++ tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h
@@ -0,0 +1,23 @@
+//==-- loop_proto_to_llvm.h - Protobuf-C++ conversion ==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// Defines functions for converting between protobufs and LLVM IR.
+//
+//===--===//
+
+#include 
+#include 
+#include 
+
+namespace clang_fuzzer {
+class LoopFunction;
+
+std::string LoopFunctionToLLVMString(const LoopFunction );
+std::string LoopProtoToLLVM(const uint8_t *data, size_t size);
+}
Index: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
===
--- /dev/null
+++ tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
@@ -0,0 +1,179 @@
+//==-- loop_proto_to_llvm.cpp - Protobuf-C++ conversion
+//-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// Implements functions for converting between protobufs and LLVM IR.
+//
+//
+//===--===//
+
+#include "loop_proto_to_llvm.h"
+#include "cxx_loop_proto.pb.h"
+
+// The following is needed to convert protos in human-readable form
+#include 
+
+#include 
+#include 
+
+namespace clang_fuzzer {
+
+// Forward decls
+std::pair  BinopToString(const BinaryOp );
+std::pair  StateSeqToString(const StatementSeq );
+
+// Counter variable to generate new LLVM IR variable names and wrapper function
+int ctr = 0;
+std::string get_var() {
+  ctr++;
+  return "%var" + std::to_string(ctr);
+}
+
+// Proto to LLVM.
+
+std::pair  ConstToString(const Const ) {
+  std::string alloca_var = get_var();
+  std::string load_var = get_var();
+  std::string val = std::to_string(x.val());
+  std::string insns = alloca_var + " = alloca i32\n"
+   + "store i32 " + val + ", i32* " + alloca_var + "\n"
+   + load_var + " = load i32, i32* " + alloca_var + "\n";
+  return std::make_pair(insns, load_var);
+}
+std::pair  VarRefToString(const VarRef ) {
+  std::string arr;
+  switch(x.arr()) {
+  case VarRef::ARR_A:
+arr = "%a";
+break;
+  case VarRef::ARR_B:
+arr = 

[PATCH] D48134: [CodeGen] make nan builtins pure rather than const (PR37778)

2018-06-13 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

Can we mark these as `argmemonly`?


Repository:
  rL LLVM

https://reviews.llvm.org/D48134



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48106: implemented proto to llvm

2018-06-13 Thread Emmett Neyman via Phabricator via cfe-commits
emmettneyman added a comment.

In https://reviews.llvm.org/D48106#1130581, @morehouse wrote:

> Where is the fuzz target?


I wanted to implement the proto_to_llvm converter before the fuzz target.


Repository:
  rC Clang

https://reviews.llvm.org/D48106



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48106: implemented proto to llvm

2018-06-13 Thread Emmett Neyman via Phabricator via cfe-commits
emmettneyman updated this revision to Diff 151239.
emmettneyman added a comment.

- refactored loop_proto_to_llvm.cpp


Repository:
  rC Clang

https://reviews.llvm.org/D48106

Files:
  tools/clang-fuzzer/CMakeLists.txt
  tools/clang-fuzzer/cxx_loop_proto.proto
  tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp
  tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx_main.cpp
  tools/clang-fuzzer/proto-to-llvm/CMakeLists.txt
  tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
  tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h
  tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp

Index: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp
===
--- tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp
+++ tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp
@@ -1,32 +1,31 @@
-//==-- loop_proto_to_cxx_main.cpp - Driver for protobuf-C++ conversion -==//
+//==-- loop_proto_to_llvm_main.cpp - Driver for protobuf-LLVM conversion==//
 //
 // The LLVM Compiler Infrastructure
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===--===//
 //
-// Implements a simple driver to print a C++ program from a protobuf with loops.
+// Implements a simple driver to print a LLVM program from a protobuf with loops
 //
 //===--===//
 
-// This is a copy and will be updated later to introduce changes
 
 #include 
 #include 
 #include 
 #include 
 
-#include "proto_to_cxx.h"
+#include "loop_proto_to_llvm.h"
 
 int main(int argc, char **argv) {
   for (int i = 1; i < argc; i++) {
 std::fstream in(argv[i]);
 std::string str((std::istreambuf_iterator(in)),
 std::istreambuf_iterator());
-std::cout << "// " << argv[i] << std::endl;
-std::cout << clang_fuzzer::LoopProtoToCxx(
+std::cout << ";; " << argv[i] << std::endl;
+std::cout << clang_fuzzer::LoopProtoToLLVM(
 reinterpret_cast(str.data()), str.size());
   }
 }
Index: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h
===
--- /dev/null
+++ tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h
@@ -0,0 +1,23 @@
+//==-- loop_proto_to_llvm.h - Protobuf-C++ conversion ==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// Defines functions for converting between protobufs and LLVM IR.
+//
+//===--===//
+
+#include 
+#include 
+#include 
+
+namespace clang_fuzzer {
+class LoopFunction;
+
+std::string LoopFunctionToLLVMString(const LoopFunction );
+std::string LoopProtoToLLVM(const uint8_t *data, size_t size);
+}
Index: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
===
--- /dev/null
+++ tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
@@ -0,0 +1,179 @@
+//==-- loop_proto_to_llvm.cpp - Protobuf-C++ conversion
+//-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// Implements functions for converting between protobufs and LLVM IR.
+//
+//
+//===--===//
+
+#include "loop_proto_to_llvm.h"
+#include "cxx_loop_proto.pb.h"
+
+// The following is needed to convert protos in human-readable form
+#include 
+
+#include 
+#include 
+
+namespace clang_fuzzer {
+
+// Forward decls
+std::pair  BinopToString(const BinaryOp );
+std::pair  StateSeqToString(const StatementSeq );
+
+// Counter variable to generate new LLVM IR variable names and wrapper function
+int ctr = 0;
+std::string get_var() {
+  ctr++;
+  return "%var" + std::to_string(ctr);
+}
+
+// Proto to LLVM.
+
+std::pair  ConstToString(const Const ) {
+  std::string alloca_var = get_var();
+  std::string load_var = get_var();
+  std::string val = std::to_string(x.val());
+  std::string insns = alloca_var + " = alloca i32\n"
+   + "store i32 " + val + ", i32* " + alloca_var + "\n"
+   + load_var + " = load i32, i32* " + alloca_var + "\n";
+  return std::make_pair(insns, load_var);
+}
+std::pair  VarRefToString(const VarRef ) {
+  std::string arr;
+  switch(x.arr()) {
+  case VarRef::ARR_A:
+arr = "%a";
+break;
+  case VarRef::ARR_B:
+arr = 

[PATCH] D48040: Implement constexpr __builtin_*_overflow

2018-06-13 Thread Eli Friedman via Phabricator via cfe-commits
efriedma added a comment.

Oh, sorry, I mixed up the two values.  I meant that you should add a couple 
testcases to ensure the stored value is correct on overflow.


https://reviews.llvm.org/D48040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48132: [COFF] Add ARM64 intrinsics: __yield, __wfe, __wfi, __sev, __sevl

2018-06-13 Thread Mandeep Singh Grang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL334639: [COFF] Add ARM64 intrinsics: __yield, __wfe, __wfi, 
__sev, __sevl (authored by mgrang, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D48132?vs=151186=151218#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D48132

Files:
  cfe/trunk/include/clang/Basic/BuiltinsAArch64.def
  cfe/trunk/lib/CodeGen/CGBuiltin.cpp
  cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c


Index: cfe/trunk/include/clang/Basic/BuiltinsAArch64.def
===
--- cfe/trunk/include/clang/Basic/BuiltinsAArch64.def
+++ cfe/trunk/include/clang/Basic/BuiltinsAArch64.def
@@ -65,9 +65,15 @@
 BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
 BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
 
+// MSVC
 LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__yield, "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfe,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfi,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__sev,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__sevl,  "v", "",   ALL_MS_LANGUAGES)
 
 // MSVC intrinsics for volatile but non-acquire/release loads and stores
 LANGBUILTIN(__iso_volatile_load8,   "ccCD*", "n", ALL_MS_LANGUAGES)
Index: cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c
===
--- cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c
+++ cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c
@@ -24,3 +24,38 @@
 
 // CHECK-MSVC: @llvm.aarch64.isb(i32 0)
 // CHECK-LINUX: error: implicit declaration of function '__isb'
+
+void check__yield(void) {
+  __yield();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 1)
+// CHECK-LINUX: error: implicit declaration of function '__yield'
+
+void check__wfe(void) {
+  __wfe();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 2)
+// CHECK-LINUX: error: implicit declaration of function '__wfe'
+
+void check__wfi(void) {
+  __wfi();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 3)
+// CHECK-LINUX: error: implicit declaration of function '__wfi'
+
+void check__sev(void) {
+  __sev();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 4)
+// CHECK-LINUX: error: implicit declaration of function '__sev'
+
+void check__sevl(void) {
+  __sevl();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 5)
+// CHECK-LINUX: error: implicit declaration of function '__sevl'
Index: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
===
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp
@@ -6362,18 +6362,23 @@
 HintID = 0;
 break;
   case AArch64::BI__builtin_arm_yield:
+  case AArch64::BI__yield:
 HintID = 1;
 break;
   case AArch64::BI__builtin_arm_wfe:
+  case AArch64::BI__wfe:
 HintID = 2;
 break;
   case AArch64::BI__builtin_arm_wfi:
+  case AArch64::BI__wfi:
 HintID = 3;
 break;
   case AArch64::BI__builtin_arm_sev:
+  case AArch64::BI__sev:
 HintID = 4;
 break;
   case AArch64::BI__builtin_arm_sevl:
+  case AArch64::BI__sevl:
 HintID = 5;
 break;
   }


Index: cfe/trunk/include/clang/Basic/BuiltinsAArch64.def
===
--- cfe/trunk/include/clang/Basic/BuiltinsAArch64.def
+++ cfe/trunk/include/clang/Basic/BuiltinsAArch64.def
@@ -65,9 +65,15 @@
 BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
 BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
 
+// MSVC
 LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__yield, "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfe,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfi,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__sev,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__sevl,  "v", "",   ALL_MS_LANGUAGES)
 
 // MSVC intrinsics for volatile but non-acquire/release loads and stores
 LANGBUILTIN(__iso_volatile_load8,   "ccCD*", "n", ALL_MS_LANGUAGES)
Index: cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c
===
--- cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c
+++ cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c
@@ -24,3 +24,38 @@
 
 // CHECK-MSVC: @llvm.aarch64.isb(i32 0)
 // CHECK-LINUX: error: implicit declaration of function '__isb'
+
+void check__yield(void) {
+  __yield();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 1)
+// CHECK-LINUX: error: implicit declaration of function '__yield'
+
+void check__wfe(void) {
+  __wfe();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 2)
+// CHECK-LINUX: error: implicit declaration of function '__wfe'
+
+void check__wfi(void) {
+  __wfi();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 3)
+// CHECK-LINUX: error: 

r334639 - [COFF] Add ARM64 intrinsics: __yield, __wfe, __wfi, __sev, __sevl

2018-06-13 Thread Mandeep Singh Grang via cfe-commits
Author: mgrang
Date: Wed Jun 13 11:49:35 2018
New Revision: 334639

URL: http://llvm.org/viewvc/llvm-project?rev=334639=rev
Log:
[COFF] Add ARM64 intrinsics: __yield, __wfe, __wfi, __sev, __sevl

Summary: These intrinsics result in hint instructions. They are provided here 
for MSVC ARM64 compatibility.

Reviewers: mstorsjo, compnerd, javed.absar

Reviewed By: mstorsjo

Subscribers: kristof.beyls, chrib, cfe-commits

Differential Revision: https://reviews.llvm.org/D48132

Modified:
cfe/trunk/include/clang/Basic/BuiltinsAArch64.def
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c

Modified: cfe/trunk/include/clang/Basic/BuiltinsAArch64.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsAArch64.def?rev=334639=334638=334639=diff
==
--- cfe/trunk/include/clang/Basic/BuiltinsAArch64.def (original)
+++ cfe/trunk/include/clang/Basic/BuiltinsAArch64.def Wed Jun 13 11:49:35 2018
@@ -65,9 +65,15 @@ BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc
 BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
 BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
 
+// MSVC
 LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__yield, "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfe,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfi,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__sev,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__sevl,  "v", "",   ALL_MS_LANGUAGES)
 
 // MSVC intrinsics for volatile but non-acquire/release loads and stores
 LANGBUILTIN(__iso_volatile_load8,   "ccCD*", "n", ALL_MS_LANGUAGES)

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=334639=334638=334639=diff
==
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Wed Jun 13 11:49:35 2018
@@ -6362,18 +6362,23 @@ Value *CodeGenFunction::EmitAArch64Built
 HintID = 0;
 break;
   case AArch64::BI__builtin_arm_yield:
+  case AArch64::BI__yield:
 HintID = 1;
 break;
   case AArch64::BI__builtin_arm_wfe:
+  case AArch64::BI__wfe:
 HintID = 2;
 break;
   case AArch64::BI__builtin_arm_wfi:
+  case AArch64::BI__wfi:
 HintID = 3;
 break;
   case AArch64::BI__builtin_arm_sev:
+  case AArch64::BI__sev:
 HintID = 4;
 break;
   case AArch64::BI__builtin_arm_sevl:
+  case AArch64::BI__sevl:
 HintID = 5;
 break;
   }

Modified: cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c?rev=334639=334638=334639=diff
==
--- cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c (original)
+++ cfe/trunk/test/CodeGen/arm64-microsoft-intrinsics.c Wed Jun 13 11:49:35 2018
@@ -24,3 +24,38 @@ void check__isb(void) {
 
 // CHECK-MSVC: @llvm.aarch64.isb(i32 0)
 // CHECK-LINUX: error: implicit declaration of function '__isb'
+
+void check__yield(void) {
+  __yield();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 1)
+// CHECK-LINUX: error: implicit declaration of function '__yield'
+
+void check__wfe(void) {
+  __wfe();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 2)
+// CHECK-LINUX: error: implicit declaration of function '__wfe'
+
+void check__wfi(void) {
+  __wfi();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 3)
+// CHECK-LINUX: error: implicit declaration of function '__wfi'
+
+void check__sev(void) {
+  __sev();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 4)
+// CHECK-LINUX: error: implicit declaration of function '__sev'
+
+void check__sevl(void) {
+  __sevl();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 5)
+// CHECK-LINUX: error: implicit declaration of function '__sevl'


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48132: [COFF] Add ARM64 intrinsics: __yield, __wfe, __wfi, __sev, __sevl

2018-06-13 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo accepted this revision.
mstorsjo added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rC Clang

https://reviews.llvm.org/D48132



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48040: Implement constexpr __builtin_*_overflow

2018-06-13 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

I believe my tests DO validate the return value correctly, don't they?  It uses 
a sentinel, but the ternary should check that return value, right?

Or is there an obvious thing I'm missing?


https://reviews.llvm.org/D48040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48040: Implement constexpr __builtin_*_overflow

2018-06-13 Thread Eli Friedman via Phabricator via cfe-commits
efriedma accepted this revision.
efriedma added a comment.
This revision is now accepted and ready to land.

I'd like to see a couple of testcases ensuring the return value is correct on 
overflow (we had a problem with that for __builtin_mul_overflow in the past).

Otherwise LGTM.


https://reviews.llvm.org/D48040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r334636 - [analyzer] Fix offset overflow check in MemRegion

2018-06-13 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Wed Jun 13 11:32:19 2018
New Revision: 334636

URL: http://llvm.org/viewvc/llvm-project?rev=334636=rev
Log:
[analyzer] Fix offset overflow check in MemRegion

rdar://39593879
https://bugs.llvm.org/show_bug.cgi?id=37142

Differential Revision: https://reviews.llvm.org/D48139

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp
cfe/trunk/test/Analysis/region_store_overflow.c

Modified: cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp?rev=334636=334635=334636=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp Wed Jun 13 11:32:19 2018
@@ -41,6 +41,7 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/CheckedArithmetic.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -1181,38 +1182,8 @@ const SymbolicRegion *MemRegion::getSymb
   return nullptr;
 }
 
-/// Perform a given operation on two integers, return whether it overflows.
-/// Optionally write the resulting output into \p Res.
-static bool checkedOp(
-int64_t LHS,
-int64_t RHS,
-std::function Op,
-int64_t *Res = nullptr) {
-  llvm::APInt ALHS(/*BitSize=*/64, LHS, /*Signed=*/true);
-  llvm::APInt ARHS(/*BitSize=*/64, RHS, /*Signed=*/true);
-  bool Overflow;
-  llvm::APInt Out = Op(, ARHS, Overflow);
-  if (!Overflow && Res)
-*Res = Out.getSExtValue();
-  return Overflow;
-}
-
-static bool checkedAdd(
-int64_t LHS,
-int64_t RHS,
-int64_t *Res=nullptr) {
-  return checkedOp(LHS, RHS, ::APInt::sadd_ov, Res);
-}
-
-static bool checkedMul(
-int64_t LHS,
-int64_t RHS,
-int64_t *Res=nullptr) {
-  return checkedOp(LHS, RHS, ::APInt::smul_ov, Res);
-}
-
 RegionRawOffset ElementRegion::getAsArrayOffset() const {
-  CharUnits offset = CharUnits::Zero();
+  int64_t offset = 0;
   const ElementRegion *ER = this;
   const MemRegion *superR = nullptr;
   ASTContext  = getContext();
@@ -1224,7 +1195,7 @@ RegionRawOffset ElementRegion::getAsArra
 
 // FIXME: generalize to symbolic offsets.
 SVal index = ER->getIndex();
-if (Optional CI = index.getAs()) 
{
+if (auto CI = index.getAs()) {
   // Update the offset.
   int64_t i = CI->getValue().getSExtValue();
 
@@ -1237,20 +1208,15 @@ RegionRawOffset ElementRegion::getAsArra
   break;
 }
 
-CharUnits size = C.getTypeSizeInChars(elemType);
-
-int64_t Mult;
-bool Overflow = checkedAdd(i, size.getQuantity(), );
-if (!Overflow)
-  Overflow = checkedMul(Mult, offset.getQuantity());
-if (Overflow) {
+int64_t size = C.getTypeSizeInChars(elemType).getQuantity();
+if (auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
+  offset = *NewOffset;
+} else {
   LLVM_DEBUG(llvm::dbgs() << "MemRegion::getAsArrayOffset: "
   << "offset overflowing, returning 
unknown\n");
 
   return nullptr;
 }
-
-offset += (i * size);
   }
 
   // Go to the next ElementRegion (if any).
@@ -1262,7 +1228,7 @@ RegionRawOffset ElementRegion::getAsArra
   }
 
   assert(superR && "super region cannot be NULL");
-  return RegionRawOffset(superR, offset);
+  return RegionRawOffset(superR, CharUnits::fromQuantity(offset));
 }
 
 /// Returns true if \p Base is an immediate base class of \p Child

Modified: cfe/trunk/test/Analysis/region_store_overflow.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/region_store_overflow.c?rev=334636=334635=334636=diff
==
--- cfe/trunk/test/Analysis/region_store_overflow.c (original)
+++ cfe/trunk/test/Analysis/region_store_overflow.c Wed Jun 13 11:32:19 2018
@@ -1,6 +1,5 @@
 // RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core -verify %s
 
-// expected-no-diagnostics
 int **h;
 int overflow_in_memregion(long j) {
   for (int l = 0;; ++l) {
@@ -9,3 +8,9 @@ int overflow_in_memregion(long j) {
   }
   return 0;
 }
+
+void rdar39593879(long long *d) {
+  long e, f;
+  e = f = d[1]; // no-crash
+  for (; d[e];) f-- > 0; // expected-warning{{relational comparison result 
unused}}; 
+}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48100: Append new attributes to the end of an AttributeList.

2018-06-13 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur updated this revision to Diff 151209.
Meinersbur added a comment.

- Remove obsolete comment
- Refactor getOrderedEnableIfAttrs


Repository:
  rC Clang

https://reviews.llvm.org/D48100

Files:
  include/clang/Sema/AttributeList.h
  lib/AST/ItaniumMangle.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/SemaOverload.cpp
  test/Index/annotate-comments-availability-attrs.cpp
  test/Index/complete-with-annotations.cpp
  test/Misc/ast-print-pragmas.cpp
  test/PCH/pragma-loop.cpp
  test/Parser/pragma-loop-safety.cpp
  test/Parser/pragma-loop.cpp
  test/Parser/pragma-unroll.cpp
  test/Sema/attr-availability-tvos.c
  test/Sema/attr-availability.c
  test/Sema/attr-coldhot.c
  test/Sema/attr-disable-tail-calls.c
  test/Sema/attr-long-call.c
  test/Sema/attr-micromips.c
  test/Sema/attr-notail.c
  test/Sema/attr-ownership.c
  test/Sema/attr-ownership.cpp
  test/Sema/attr-print.c
  test/Sema/attr-swiftcall.c
  test/Sema/attr-target-mv.c
  test/Sema/attr-visibility.c
  test/Sema/internal_linkage.c
  test/Sema/mips-interrupt-attr.c
  test/Sema/ms_abi-sysv_abi.c
  test/Sema/nullability.c
  test/Sema/stdcall-fastcall.c
  test/SemaCXX/attr-print.cpp
  test/SemaCXX/attr-swiftcall.cpp
  test/SemaCXX/decl-microsoft-call-conv.cpp
  test/SemaCXX/ms-uuid.cpp
  test/SemaOpenCL/address-spaces.cl
  test/SemaTemplate/attributes.cpp

Index: test/SemaTemplate/attributes.cpp
===
--- test/SemaTemplate/attributes.cpp
+++ test/SemaTemplate/attributes.cpp
@@ -55,11 +55,11 @@
 }
 
 // CHECK: FunctionTemplateDecl {{.*}} HasAnnotations
-// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_BAR"
 // CHECK:   AnnotateAttr {{.*}} "ANNOTATE_FOO"
+// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_BAR"
 // CHECK: FunctionDecl {{.*}} HasAnnotations
 // CHECK:   TemplateArgument type 'int'
-// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_BAR"
 // CHECK:   AnnotateAttr {{.*}} "ANNOTATE_FOO"
+// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_BAR"
 template [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations();
 void UseAnnotations() { HasAnnotations(); }
Index: test/SemaOpenCL/address-spaces.cl
===
--- test/SemaOpenCL/address-spaces.cl
+++ test/SemaOpenCL/address-spaces.cl
@@ -58,8 +58,8 @@
 
 void func_multiple_addr(void) {
   typedef __private int private_int_t;
-  __local __private int var1;   // expected-error {{multiple address spaces specified for type}}
-  __local __private int *var2;  // expected-error {{multiple address spaces specified for type}}
+  __private __local int var1;   // expected-error {{multiple address spaces specified for type}}
+  __private __local int *var2;  // expected-error {{multiple address spaces specified for type}}
   __local private_int_t var3;   // expected-error {{multiple address spaces specified for type}}
   __local private_int_t *var4;  // expected-error {{multiple address spaces specified for type}}
 }
Index: test/SemaCXX/ms-uuid.cpp
===
--- test/SemaCXX/ms-uuid.cpp
+++ test/SemaCXX/ms-uuid.cpp
@@ -62,14 +62,14 @@
 [uuid("22A0---C000-0049")] class C4 {};
 
 // Both cl and clang-cl error out on this:
-// expected-note@+1 {{previous uuid specified here}}
-class __declspec(uuid("00A0---C000-0049"))
 // expected-error@+1 {{uuid does not match previous declaration}}
+class __declspec(uuid("00A0---C000-0049"))
+// expected-note@+1 {{previous uuid specified here}}
   __declspec(uuid("11A0---C000-0049")) C5;
 
-// expected-note@+1 {{previous uuid specified here}}
-[uuid("00A0---C000-0049"),
 // expected-error@+1 {{uuid does not match previous declaration}}
+[uuid("00A0---C000-0049"),
+// expected-note@+1 {{previous uuid specified here}}
  uuid("11A0---C000-0049")] class C6;
 
 // cl doesn't diagnose having one uuid each as []-style attributes and as
Index: test/SemaCXX/decl-microsoft-call-conv.cpp
===
--- test/SemaCXX/decl-microsoft-call-conv.cpp
+++ test/SemaCXX/decl-microsoft-call-conv.cpp
@@ -161,7 +161,7 @@
 // expected-error@+3 {{vectorcall and cdecl attributes are not compatible}}
 // expected-error@+2 {{stdcall and cdecl attributes are not compatible}}
 // expected-error@+1 {{fastcall and cdecl attributes are not compatible}}
-void __cdecl __cdecl __stdcall __cdecl __fastcall __vectorcall multi_cc(int x);
+void __vectorcall __fastcall __cdecl __stdcall __cdecl __cdecl multi_cc(int x);
 
 template  void __stdcall StdcallTemplate(T) {}
 template <> void StdcallTemplate(int) {}
Index: test/SemaCXX/attr-swiftcall.cpp
===
--- test/SemaCXX/attr-swiftcall.cpp
+++ test/SemaCXX/attr-swiftcall.cpp
@@ -7,7 +7,7 @@
 
 int notAFunction SWIFTCALL; // 

[PATCH] D47044: [analyzer] Ensure that we only visit a destructor for a reference if type information is available.

2018-06-13 Thread Matthew Voss via Phabricator via cfe-commits
ormris added a comment.

Thanks @george.karpenkov . I was wondering why it didn't close automatically.


Repository:
  rC Clang

https://reviews.llvm.org/D47044



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45616: [X86] Lower _mm[256|512]_cmp[.]_mask intrinsics to native llvm IR

2018-06-13 Thread Sanjay Patel via Phabricator via cfe-commits
spatel added inline comments.



Comment at: lib/CodeGen/CGBuiltin.cpp:10107-10112
+case 0x0b: // FALSE_OQ
+case 0x1b: // FALSE_OS
+  return llvm::Constant::getNullValue(ConvertType(E->getType()));
+case 0x0f: // TRUE_UQ
+case 0x1f: // TRUE_US
+  return llvm::Constant::getAllOnesValue(ConvertType(E->getType()));

On 2nd thought, why are we optimizing when we have matching IR predicates for 
these?
Just translate to FCMP_TRUE / FCMP_FALSE instead of special-casing these values.
InstSimplify can handle the constant folding if optimization is on.


https://reviews.llvm.org/D45616



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47044: [analyzer] Ensure that we only visit a destructor for a reference if type information is available.

2018-06-13 Thread George Karpenkov via Phabricator via cfe-commits
george.karpenkov added a comment.

> This change has been committed, so I'm closing this review.

@ormris The process which should be followed here is to add a line (exactly) 
"Differential Revision: https://reviews.llvm.org/D47044; to the bottom of your 
commit message, so that the phabricator can cross-reference the review and the 
commit.
Alternatively, you could use the "arc" tool which would do that for you.


Repository:
  rC Clang

https://reviews.llvm.org/D47044



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45616: [X86] Lower _mm[256|512]_cmp[.]_mask intrinsics to native llvm IR

2018-06-13 Thread Gabor Buella via Phabricator via cfe-commits
GBuella updated this revision to Diff 151203.
GBuella edited the summary of this revision.
GBuella added a comment.

Ignoring signaling behviour - and rounding mode with it.
Also lowering `__builtin_ia32_cmpsd` and `__builtin_ia32_cmpss`.


https://reviews.llvm.org/D45616

Files:
  lib/CodeGen/CGBuiltin.cpp
  test/CodeGen/avx-builtins.c
  test/CodeGen/avx-cmp-builtins.c
  test/CodeGen/avx2-builtins.c
  test/CodeGen/avx512f-builtins.c
  test/CodeGen/avx512vl-builtins.c

Index: test/CodeGen/avx512vl-builtins.c
===
--- test/CodeGen/avx512vl-builtins.c
+++ test/CodeGen/avx512vl-builtins.c
@@ -1073,53 +1073,168 @@
 
 __mmask8 test_mm256_cmp_ps_mask(__m256 __A, __m256 __B) {
   // CHECK-LABEL: @test_mm256_cmp_ps_mask
-  // CHECK: call <8 x i1> @llvm.x86.avx512.mask.cmp.ps.256
+  // CHECK: fcmp oeq <8 x float> %{{.*}}, %{{.*}}
   return (__mmask8)_mm256_cmp_ps_mask(__A, __B, 0);
 }
 
+__mmask8 test_mm256_cmp_ps_mask_true_uq(__m256 __A, __m256 __B) {
+  // CHECK-LABEL: @test_mm256_cmp_ps_mask_true_uq
+  // CHECK-NOT: call
+  // CHECK: ret i8 -1
+  return (__mmask8)_mm256_cmp_ps_mask(__A, __B, _CMP_TRUE_UQ);
+}
+
+__mmask8 test_mm256_cmp_ps_mask_true_us(__m256 __A, __m256 __B) {
+  // CHECK-LABEL: @test_mm256_cmp_ps_mask_true_us
+  // CHECK-NOT: call
+  // CHECK: ret i8 -1
+  return (__mmask8)_mm256_cmp_ps_mask(__A, __B, _CMP_TRUE_US);
+}
+
+__mmask8 test_mm256_cmp_ps_mask_false_oq(__m256 __A, __m256 __B) {
+  // CHECK-LABEL: @test_mm256_cmp_ps_mask_false_oq
+  // CHECK-NOT: call
+  // CHECK: ret i8 0
+  return (__mmask8)_mm256_cmp_ps_mask(__A, __B, _CMP_FALSE_OQ);
+}
+
+__mmask8 test_mm256_cmp_ps_mask_false_os(__m256 __A, __m256 __B) {
+  // CHECK-LABEL: @test_mm256_cmp_ps_mask_false_os
+  // CHECK-NOT: call
+  // CHECK: ret i8 0
+  return (__mmask8)_mm256_cmp_ps_mask(__A, __B, _CMP_FALSE_OS);
+}
+
 __mmask8 test_mm256_mask_cmp_ps_mask(__mmask8 m, __m256 __A, __m256 __B) {
   // CHECK-LABEL: @test_mm256_mask_cmp_ps_mask
-  // CHECK: [[CMP:%.*]] = call <8 x i1> @llvm.x86.avx512.mask.cmp.ps.256
-  // CHECK: and <8 x i1> [[CMP]], {{.*}}
+  // CHECK: fcmp oeq <8 x float> %{{.*}}, %{{.*}}
+  // CHECK: and <8 x i1> %{{.*}}, %{{.*}}
   return _mm256_mask_cmp_ps_mask(m, __A, __B, 0);
 }
 
 __mmask8 test_mm_cmp_ps_mask(__m128 __A, __m128 __B) {
   // CHECK-LABEL: @test_mm_cmp_ps_mask
-  // CHECK: call <4 x i1> @llvm.x86.avx512.mask.cmp.ps.128
+  // CHECK: fcmp oeq <4 x float> %{{.*}}, %{{.*}}
   return (__mmask8)_mm_cmp_ps_mask(__A, __B, 0);
 }
 
+__mmask8 test_mm_cmp_ps_mask_true_uq(__m128 __A, __m128 __B) {
+  // CHECK-LABEL: @test_mm_cmp_ps_mask_true_uq
+  // CHECK-NOT: call
+  // CHECK: ret i8 -1
+  return (__mmask8)_mm_cmp_ps_mask(__A, __B, _CMP_TRUE_UQ);
+}
+
+__mmask8 test_mm_cmp_ps_mask_true_us(__m128 __A, __m128 __B) {
+  // CHECK-LABEL: @test_mm_cmp_ps_mask_true_us
+  // CHECK-NOT: call
+  // CHECK: ret i8 -1
+  return (__mmask8)_mm_cmp_ps_mask(__A, __B, _CMP_TRUE_US);
+}
+
+__mmask8 test_mm_cmp_ps_mask_false_oq(__m128 __A, __m128 __B) {
+  // CHECK-LABEL: @test_mm_cmp_ps_mask_false_oq
+  // CHECK-NOT: call
+  // CHECK: ret i8 0
+  return (__mmask8)_mm_cmp_ps_mask(__A, __B, _CMP_FALSE_OQ);
+}
+
+__mmask8 test_mm_cmp_ps_mask_false_os(__m128 __A, __m128 __B) {
+  // CHECK-LABEL: @test_mm_cmp_ps_mask_false_os
+  // CHECK-NOT: call
+  // CHECK: ret i8 0
+  return (__mmask8)_mm_cmp_ps_mask(__A, __B, _CMP_FALSE_OS);
+}
+
 __mmask8 test_mm_mask_cmp_ps_mask(__mmask8 m, __m128 __A, __m128 __B) {
   // CHECK-LABEL: @test_mm_mask_cmp_ps_mask
-  // CHECK: [[CMP:%.*]] = call <4 x i1> @llvm.x86.avx512.mask.cmp.ps.128
-  // CHECK: and <4 x i1> [[CMP]], {{.*}}
+  // CHECK: fcmp oeq <4 x float> %{{.*}}, %{{.*}}
+  // CHECK: shufflevector <8 x i1> %{{.*}}, <8 x i1> %{{.*}}, <4 x i32> 
+  // CHECK: and <4 x i1> %{{.*}}, %{{.*}}
   return _mm_mask_cmp_ps_mask(m, __A, __B, 0);
 }
 
 __mmask8 test_mm256_cmp_pd_mask(__m256d __A, __m256d __B) {
   // CHECK-LABEL: @test_mm256_cmp_pd_mask
-  // CHECK: call <4 x i1> @llvm.x86.avx512.mask.cmp.pd.256
+  // CHECK: fcmp oeq <4 x double> %{{.*}}, %{{.*}}
   return (__mmask8)_mm256_cmp_pd_mask(__A, __B, 0);
 }
 
+__mmask8 test_mm256_cmp_pd_mask_true_uq(__m256d __A, __m256d __B) {
+  // CHECK-LABEL: @test_mm256_cmp_pd_mask_true_uq
+  // CHECK-NOT: call
+  // CHECK: ret i8 -1
+  return (__mmask8)_mm256_cmp_pd_mask(__A, __B, _CMP_TRUE_UQ);
+}
+
+__mmask8 test_mm256_cmp_pd_mask_true_us(__m256d __A, __m256d __B) {
+  // CHECK-LABEL: @test_mm256_cmp_pd_mask_true_us
+  // CHECK-NOT: call
+  // CHECK: ret i8 -1
+  return (__mmask8)_mm256_cmp_pd_mask(__A, __B, _CMP_TRUE_US);
+}
+
+__mmask8 test_mm256_cmp_pd_mask_false_oq(__m256d __A, __m256d __B) {
+  // CHECK-LABEL: @test_mm256_cmp_pd_mask_false_oq
+  // CHECK-NOT: call
+  // CHECK: ret i8 0
+  return (__mmask8)_mm256_cmp_pd_mask(__A, __B, _CMP_FALSE_OQ);
+}
+
+__mmask8 test_mm256_cmp_pd_mask_false_os(__m256d __A, __m256d __B) {
+  // CHECK-LABEL: @test_mm256_cmp_pd_mask_false_os
+  // 

[PATCH] D48134: [CodeGen] make nan builtins pure rather than const (PR37778)

2018-06-13 Thread Sanjay Patel via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL334628: [CodeGen] make nan builtins pure rather than const 
(PR37778) (authored by spatel, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D48134?vs=151187=151202#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D48134

Files:
  cfe/trunk/include/clang/Basic/Builtins.def
  cfe/trunk/test/CodeGen/math-builtins.c


Index: cfe/trunk/include/clang/Basic/Builtins.def
===
--- cfe/trunk/include/clang/Basic/Builtins.def
+++ cfe/trunk/include/clang/Basic/Builtins.def
@@ -137,14 +137,14 @@
 BUILTIN(__builtin_modf , "ddd*"  , "Fn")
 BUILTIN(__builtin_modff, "fff*"  , "Fn")
 BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
-BUILTIN(__builtin_nan,  "dcC*" , "ncF")
-BUILTIN(__builtin_nanf, "fcC*" , "ncF")
-BUILTIN(__builtin_nanl, "LdcC*", "ncF")
-BUILTIN(__builtin_nanf128, "LLdcC*", "ncF")
-BUILTIN(__builtin_nans,  "dcC*" , "ncF")
-BUILTIN(__builtin_nansf, "fcC*" , "ncF")
-BUILTIN(__builtin_nansl, "LdcC*", "ncF")
-BUILTIN(__builtin_nansf128, "LLdcC*", "ncF")
+BUILTIN(__builtin_nan,  "dcC*" , "FnU")
+BUILTIN(__builtin_nanf, "fcC*" , "FnU")
+BUILTIN(__builtin_nanl, "LdcC*", "FnU")
+BUILTIN(__builtin_nanf128, "LLdcC*", "FnU")
+BUILTIN(__builtin_nans,  "dcC*" , "FnU")
+BUILTIN(__builtin_nansf, "fcC*" , "FnU")
+BUILTIN(__builtin_nansl, "LdcC*", "FnU")
+BUILTIN(__builtin_nansf128, "LLdcC*", "FnU")
 BUILTIN(__builtin_powi , "ddi"  , "Fnc")
 BUILTIN(__builtin_powif, "ffi"  , "Fnc")
 BUILTIN(__builtin_powil, "LdLdi", "Fnc")
Index: cfe/trunk/test/CodeGen/math-builtins.c
===
--- cfe/trunk/test/CodeGen/math-builtins.c
+++ cfe/trunk/test/CodeGen/math-builtins.c
@@ -90,25 +90,25 @@
 
   __builtin_nan(c);__builtin_nanf(c);   __builtin_nanl(c); 
__builtin_nanf128(c);
 
-// NO__ERRNO: declare double @nan(i8*) [[READNONE]]
-// NO__ERRNO: declare float @nanf(i8*) [[READNONE]]
-// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
-// NO__ERRNO: declare fp128 @nanf128(i8*) [[READNONE]]
-// HAS_ERRNO: declare double @nan(i8*) [[READNONE:#[0-9]+]]
-// HAS_ERRNO: declare float @nanf(i8*) [[READNONE]]
-// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
-// HAS_ERRNO: declare fp128 @nanf128(i8*) [[READNONE]]
+// NO__ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]]
+// NO__ERRNO: declare float @nanf(i8*) [[PURE]]
+// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]]
+// NO__ERRNO: declare fp128 @nanf128(i8*) [[PURE]]
+// HAS_ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]]
+// HAS_ERRNO: declare float @nanf(i8*) [[PURE]]
+// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]]
+// HAS_ERRNO: declare fp128 @nanf128(i8*) [[PURE]]
 
   __builtin_nans(c);__builtin_nansf(c);   __builtin_nansl(c); 
__builtin_nansf128(c);
 
-// NO__ERRNO: declare double @nans(i8*) [[READNONE]]
-// NO__ERRNO: declare float @nansf(i8*) [[READNONE]]
-// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
-// NO__ERRNO: declare fp128 @nansf128(i8*) [[READNONE]]
-// HAS_ERRNO: declare double @nans(i8*) [[READNONE]]
-// HAS_ERRNO: declare float @nansf(i8*) [[READNONE]]
-// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
-// HAS_ERRNO: declare fp128 @nansf128(i8*) [[READNONE]]
+// NO__ERRNO: declare double @nans(i8*) [[PURE]]
+// NO__ERRNO: declare float @nansf(i8*) [[PURE]]
+// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]]
+// NO__ERRNO: declare fp128 @nansf128(i8*) [[PURE]]
+// HAS_ERRNO: declare double @nans(i8*) [[PURE]]
+// HAS_ERRNO: declare float @nansf(i8*) [[PURE]]
+// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]]
+// HAS_ERRNO: declare fp128 @nansf128(i8*) [[PURE]]
 
   __builtin_pow(f,f);__builtin_powf(f,f);   __builtin_powl(f,f);
 
@@ -188,7 +188,7 @@
 // NO__ERRNO: declare double @cbrt(double) [[READNONE]]
 // NO__ERRNO: declare float @cbrtf(float) [[READNONE]]
 // NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
-// HAS_ERRNO: declare double @cbrt(double) [[READNONE]]
+// HAS_ERRNO: declare double @cbrt(double) [[READNONE:#[0-9]+]]
 // HAS_ERRNO: declare float @cbrtf(float) [[READNONE]]
 // HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
 
@@ -581,9 +581,11 @@
 // NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
 // NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
 // NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+// NO__ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} }
 
 // HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
 // HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
+// HAS_ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} }
 // HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
 
 // HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }


Index: 

r334628 - [CodeGen] make nan builtins pure rather than const (PR37778)

2018-06-13 Thread Sanjay Patel via cfe-commits
Author: spatel
Date: Wed Jun 13 10:54:52 2018
New Revision: 334628

URL: http://llvm.org/viewvc/llvm-project?rev=334628=rev
Log:
[CodeGen] make nan builtins pure rather than const (PR37778)

https://bugs.llvm.org/show_bug.cgi?id=37778
...shows a miscompile resulting from marking nan builtins as 'const'.

The nan libcalls/builtins take a pointer argument:
http://www.cplusplus.com/reference/cmath/nan-function/
...and the chars dereferenced by that arg are used to fill in the NaN constant 
payload bits.

"const" means that the pointer argument isn't dereferenced. That's translated 
to "readnone" in LLVM.
"pure" means that the pointer argument may be dereferenced. That's translated 
to "readonly" in LLVM.

This change prevents the IR optimizer from killing the lead-up to the nan call 
here:

double a() {
  char buf[4];
  buf[0] = buf[1] = buf[2] = '9';
  buf[3] = '\0';
  return __builtin_nan(buf);
}

...the optimizer isn't currently able to simplify this to a constant as we 
might hope, 
but this patch should solve the miscompile.

Differential Revision: https://reviews.llvm.org/D48134

Modified:
cfe/trunk/include/clang/Basic/Builtins.def
cfe/trunk/test/CodeGen/math-builtins.c

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=334628=334627=334628=diff
==
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Wed Jun 13 10:54:52 2018
@@ -137,14 +137,14 @@ BUILTIN(__builtin_ldexpl, "LdLdi", "Fne"
 BUILTIN(__builtin_modf , "ddd*"  , "Fn")
 BUILTIN(__builtin_modff, "fff*"  , "Fn")
 BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
-BUILTIN(__builtin_nan,  "dcC*" , "ncF")
-BUILTIN(__builtin_nanf, "fcC*" , "ncF")
-BUILTIN(__builtin_nanl, "LdcC*", "ncF")
-BUILTIN(__builtin_nanf128, "LLdcC*", "ncF")
-BUILTIN(__builtin_nans,  "dcC*" , "ncF")
-BUILTIN(__builtin_nansf, "fcC*" , "ncF")
-BUILTIN(__builtin_nansl, "LdcC*", "ncF")
-BUILTIN(__builtin_nansf128, "LLdcC*", "ncF")
+BUILTIN(__builtin_nan,  "dcC*" , "FnU")
+BUILTIN(__builtin_nanf, "fcC*" , "FnU")
+BUILTIN(__builtin_nanl, "LdcC*", "FnU")
+BUILTIN(__builtin_nanf128, "LLdcC*", "FnU")
+BUILTIN(__builtin_nans,  "dcC*" , "FnU")
+BUILTIN(__builtin_nansf, "fcC*" , "FnU")
+BUILTIN(__builtin_nansl, "LdcC*", "FnU")
+BUILTIN(__builtin_nansf128, "LLdcC*", "FnU")
 BUILTIN(__builtin_powi , "ddi"  , "Fnc")
 BUILTIN(__builtin_powif, "ffi"  , "Fnc")
 BUILTIN(__builtin_powil, "LdLdi", "Fnc")

Modified: cfe/trunk/test/CodeGen/math-builtins.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/math-builtins.c?rev=334628=334627=334628=diff
==
--- cfe/trunk/test/CodeGen/math-builtins.c (original)
+++ cfe/trunk/test/CodeGen/math-builtins.c Wed Jun 13 10:54:52 2018
@@ -90,25 +90,25 @@ void foo(double *d, float f, float *fp,
 
   __builtin_nan(c);__builtin_nanf(c);   __builtin_nanl(c); 
__builtin_nanf128(c);
 
-// NO__ERRNO: declare double @nan(i8*) [[READNONE]]
-// NO__ERRNO: declare float @nanf(i8*) [[READNONE]]
-// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
-// NO__ERRNO: declare fp128 @nanf128(i8*) [[READNONE]]
-// HAS_ERRNO: declare double @nan(i8*) [[READNONE:#[0-9]+]]
-// HAS_ERRNO: declare float @nanf(i8*) [[READNONE]]
-// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
-// HAS_ERRNO: declare fp128 @nanf128(i8*) [[READNONE]]
+// NO__ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]]
+// NO__ERRNO: declare float @nanf(i8*) [[PURE]]
+// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]]
+// NO__ERRNO: declare fp128 @nanf128(i8*) [[PURE]]
+// HAS_ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]]
+// HAS_ERRNO: declare float @nanf(i8*) [[PURE]]
+// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]]
+// HAS_ERRNO: declare fp128 @nanf128(i8*) [[PURE]]
 
   __builtin_nans(c);__builtin_nansf(c);   __builtin_nansl(c); 
__builtin_nansf128(c);
 
-// NO__ERRNO: declare double @nans(i8*) [[READNONE]]
-// NO__ERRNO: declare float @nansf(i8*) [[READNONE]]
-// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
-// NO__ERRNO: declare fp128 @nansf128(i8*) [[READNONE]]
-// HAS_ERRNO: declare double @nans(i8*) [[READNONE]]
-// HAS_ERRNO: declare float @nansf(i8*) [[READNONE]]
-// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
-// HAS_ERRNO: declare fp128 @nansf128(i8*) [[READNONE]]
+// NO__ERRNO: declare double @nans(i8*) [[PURE]]
+// NO__ERRNO: declare float @nansf(i8*) [[PURE]]
+// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]]
+// NO__ERRNO: declare fp128 @nansf128(i8*) [[PURE]]
+// HAS_ERRNO: declare double @nans(i8*) [[PURE]]
+// HAS_ERRNO: declare float @nansf(i8*) [[PURE]]
+// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]]
+// HAS_ERRNO: declare fp128 @nansf128(i8*) [[PURE]]
 
   __builtin_pow(f,f);__builtin_powf(f,f);   __builtin_powl(f,f);
 

[PATCH] D46915: [Fixed Point Arithmetic] Fixed Point Precision Bits and Fixed Point Literals

2018-06-13 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: include/clang/Basic/TargetInfo.h:89
+  // corresponding unsaturated types.
+  unsigned char ShortAccumFBits, ShortAccumIBits;
+  unsigned char AccumFBits, AccumIBits;

ebevhan wrote:
> leonardchan wrote:
> > ebevhan wrote:
> > > leonardchan wrote:
> > > > ebevhan wrote:
> > > > > I suspect it's still possible to calculate the ibits based on the 
> > > > > fbits, even for _Accum.
> > > > > 
> > > > > Are the unsigned values needed? The fbits for unsigned _Fract are the 
> > > > > same as for signed _Fract if SameFBits is set, and +1 otherwise. The 
> > > > > same should go for unsigned _Accum, but I don't think it's entirely 
> > > > > clear how this affects the integral part.
> > > > Similar to the previous comment, if we choose to make SameFBits 
> > > > dependent on/controlled by the target, then I think it would be better 
> > > > for the target to explicitly specify the integral bits since there 
> > > > could be some cases where there may be padding (such as for unsigned 
> > > > _Accum types if this flag is set), and in this case, I think it should 
> > > > be explicit that the `bit_width != IBits + FBits`.
> > > > 
> > > > We also can't fill in that padding for the unsigned _Accum types as an 
> > > > extra integral bit since the standard says that `"each signed accum 
> > > > type has at least as many integral bits as its corresponding unsigned 
> > > > accum type".`
> > > > 
> > > > For the unsigned _Fract values, I think we can get rid of them if we 
> > > > choose to keep the flag instead, but it would no longer apply to 
> > > > unsigned _Accum types since it would allow for extra padding in these 
> > > > types and would conflict with the logic of `bit_width == IBits + FBits`
> > > > 
> > > > For now, I actually think the simplest option is to keep these target 
> > > > properties, but have the target override them individually, with checks 
> > > > to make sure the values adhere to the standard.
> > > Is it not the case that `bitwidth != IBits + FBits` for signed types 
> > > only? Signed types require a sign bit (which is neither a fractional bit 
> > > nor an integral bit, according to spec) but unsigned types do not, and if 
> > > IBits and FBits for the signed and unsigned types are the same, the MSB 
> > > is simply a padding bit, at least for _Accum (for _Fract everything above 
> > > the fbits is padding). 
> > > 
> > > My reasoning for keeping the number of configurable values down was to 
> > > limit the number of twiddly knobs to make the implementation simpler. 
> > > Granting a lot of freedom is nice, but I suspect that it will be quite 
> > > hard to get the implementation working properly for every valid 
> > > configuration. I also don't really see much of a reason for `FBits != 
> > > UFBits` in general. I know the spec gives a recommendation to implement 
> > > it that way, but I think the benefit of normalizing the signed and 
> > > unsigned representations outweighs the lost bit in the unsigned type.
> > > 
> > > It's hard to say what the differences are beyond that since I'm not sure 
> > > how you plan on treating padding bits. In our implementation, padding 
> > > bits (the MSB in all of the unsigned types for us) after any operation 
> > > are zeroed.
> > I see. The implementation would be much simpler this way. The initial idea 
> > was to treat the padding bits as "don't care" bits where we would mask only 
> > the data bits when doing operations like comparisons that look at the whole 
> > integer.
> That does work, but for binary operations it means you might need multiple 
> maskings per operation. If you mask after every operation instead, you only 
> need one. In our implementation, the only padding bit we have is the MSB in 
> the unsigned types. We simply insert a 'bit clear' after every operation that 
> produces an unsigned type (with some exceptions).
> 
> The E-C spec says that padding bits are 'unspecified', but 
> implementation-wise, they have to be defined to something in order to operate 
> on them. So long as you ensure that it is never possible to observe anything 
> but zero in those bits from a program perspective, most operations just work. 
> Naturally, there are ways to subvert this design. If you have a `signed 
> _Fract *` and cast it to an `unsigned _Fract *` and the values happen to be 
> negative, the padding bit will be set and you'll get exciting behavior.
> 
> Although... I just realized that the topmost half of the `_Fract`s in your 
> configuration is all padding. That might make things a bit more complicated 
> for things like signed types... Ideally the sign bit would be extended into 
> the padding for those.
Yeah, I initially had 2 general purpose ideas for handling the padding:

- Zero/sign extend them after all operations that modify the value (+, *, <<, 
casting to 
 another type, ...). This way we know the sign part of a fixed point type, 

[PATCH] D47672: [Headers] Add _Interlocked*_HLEAcquire/_HLERelease

2018-06-13 Thread Craig Topper via Phabricator via cfe-commits
craig.topper added a comment.

FWIW, I found a cfe-dev thread about adding HLE support 
http://lists.llvm.org/pipermail/cfe-dev/2013-February/028031.html And a bunch 
of dead patches in phabricator https://reviews.llvm.org/people/revisions/110/

I also spoke to Andi Kleen here at Intel to make sure I got these inline 
assembly versions correct. And he's not sure CPython should be using these the 
way it is. It looks like they try to use the HLE versions anytime the memory 
order is acquire/release. But HLE isn't suitable for every acquire/release.


https://reviews.llvm.org/D47672



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48134: [CodeGen] make nan builtins pure rather than const (PR37778)

2018-06-13 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri accepted this revision.
lebedev.ri added a comment.
This revision is now accepted and ready to land.

Makes sense.


https://reviews.llvm.org/D48134



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45616: [X86] Lower _mm[256|512]_cmp[.]_mask intrinsics to native llvm IR

2018-06-13 Thread Gabor Buella via Phabricator via cfe-commits
GBuella added inline comments.



Comment at: lib/CodeGen/CGBuiltin.cpp:10090-10100
+// _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector
+// on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0...
+if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) {
+   llvm::Type *ResultType = ConvertType(E->getType());
+
+   Value *Constant = (CC == 0xf || CC == 0x1f) ?
+  llvm::Constant::getAllOnesValue(ResultType) :

spatel wrote:
>   llvm::Type *ResultType = ConvertType(E->getType());
>   if (CC == 0x0f || CC == 0x1f)
> return llvm::Constant::getAllOnesValue(ResultType);
>   if (CC == 0x0b || CC == 0x1b)
> return llvm::Constant::getNullValue(ResultType);
> 
> ?
> 
> Also, can we use the defined predicate names instead of hex values in this 
> code?
Well, I believe we would need to predefine them first.
I only found those in the client header `avxintrin.h`.


https://reviews.llvm.org/D45616



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[libcxx] r334621 - Merging r323390:

2018-06-13 Thread Tom Stellard via cfe-commits
Author: tstellar
Date: Wed Jun 13 09:57:18 2018
New Revision: 334621

URL: http://llvm.org/viewvc/llvm-project?rev=334621=rev
Log:
Merging r323390:


r323390 | ericwf | 2018-01-24 16:02:48 -0800 (Wed, 24 Jan 2018) | 9 lines

Fix PR35564 - std::list splice/erase incorrectly throw in debug mode.

There was a bug in the implementation of splice where the container
sizes were updated before decrementing one of the iterators. Afterwards,
the result of decrementing the iterator was flagged as UB by the debug
implementation because the container was reported to be empty.

This patch fixes that bug by delaying the updating of the container
sizes until after the iterators have been correctly constructed.


Modified:
libcxx/branches/release_60/include/list

libcxx/branches/release_60/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp

Modified: libcxx/branches/release_60/include/list
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/branches/release_60/include/list?rev=334621=334620=334621=diff
==
--- libcxx/branches/release_60/include/list (original)
+++ libcxx/branches/release_60/include/list Wed Jun 13 09:57:18 2018
@@ -2058,15 +2058,15 @@ list<_Tp, _Alloc>::splice(const_iterator
 #endif
 if (__f != __l)
 {
+__link_pointer __first = __f.__ptr_;
+--__l;
+__link_pointer __last = __l.__ptr_;
 if (this != &__c)
 {
-size_type __s = _VSTD::distance(__f, __l);
+size_type __s = _VSTD::distance(__f, __l) + 1;
 __c.__sz() -= __s;
 base::__sz() += __s;
 }
-__link_pointer __first = __f.__ptr_;
---__l;
-__link_pointer __last = __l.__ptr_;
 base::__unlink_nodes(__first, __last);
 __link_nodes(__p.__ptr_, __first, __last);
 #if _LIBCPP_DEBUG_LEVEL >= 2

Modified: 
libcxx/branches/release_60/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/branches/release_60/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp?rev=334621=334620=334621=diff
==
--- 
libcxx/branches/release_60/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp
 (original)
+++ 
libcxx/branches/release_60/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp
 Wed Jun 13 09:57:18 2018
@@ -42,6 +42,7 @@ public:
 Base::run();
 try {
   FrontOnEmptyContainer();
+
   if constexpr (CT != CT_ForwardList) {
 AssignInvalidates();
 BackOnEmptyContainer();
@@ -50,6 +51,8 @@ public:
 InsertIterIterIter();
 EmplaceIterValue();
 EraseIterIter();
+  } else {
+SpliceFirstElemAfter();
   }
   if constexpr (CT == CT_Vector || CT == CT_Deque || CT == CT_List) {
 PopBack();
@@ -57,12 +60,66 @@ public:
   if constexpr (CT == CT_List || CT == CT_Deque) {
 PopFront(); // FIXME: Run with forward list as well
   }
+  if constexpr (CT == CT_List || CT == CT_ForwardList) {
+RemoveFirstElem();
+  }
+  if constexpr (CT == CT_List) {
+SpliceFirstElem();
+  }
 } catch (...) {
   assert(false && "uncaught debug exception");
 }
   }
 
 private:
+  static void RemoveFirstElem() {
+// See llvm.org/PR35564
+CHECKPOINT("remove()");
+{
+  Container C = makeContainer(1);
+  auto FirstVal = *(C.begin());
+  C.remove(FirstVal);
+  assert(C.empty());
+}
+{
+  Container C = {1, 1, 1, 1};
+  auto FirstVal = *(C.begin());
+  C.remove(FirstVal);
+  assert(C.empty());
+}
+  }
+
+  static void SpliceFirstElem() {
+// See llvm.org/PR35564
+CHECKPOINT("splice()");
+{
+  Container C = makeContainer(1);
+  Container C2;
+  C2.splice(C2.end(), C, C.begin(), ++C.begin());
+}
+{
+  Container C = makeContainer(1);
+  Container C2;
+  C2.splice(C2.end(), C, C.begin());
+}
+  }
+
+
+  static void SpliceFirstElemAfter() {
+// See llvm.org/PR35564
+CHECKPOINT("splice()");
+{
+  Container C = makeContainer(1);
+  Container C2;
+  C2.splice_after(C2.begin(), C, C.begin(), ++C.begin());
+}
+{
+  Container C = makeContainer(1);
+  Container C2;
+  C2.splice_after(C2.begin(), C, C.begin());
+}
+  }
+
   static void AssignInvalidates() {
 CHECKPOINT("assign(Size, Value)");
 Container C(allocator_type{});


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47044: [analyzer] Ensure that we only visit a destructor for a reference if type information is available.

2018-06-13 Thread Matthew Voss via Phabricator via cfe-commits
ormris closed this revision.
ormris added a comment.

This change has been committed, so I'm closing this review.

https://reviews.llvm.org/rC334554


Repository:
  rC Clang

https://reviews.llvm.org/D47044



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48036: [CUDA] Make min/max shims host+device.

2018-06-13 Thread Artem Belevich via Phabricator via cfe-commits
tra added a comment.

Ack.


https://reviews.llvm.org/D48036



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48134: [CodeGen] make nan builtins pure rather than const (PR37778)

2018-06-13 Thread Sanjay Patel via Phabricator via cfe-commits
spatel created this revision.
spatel added reviewers: gfalcon, lebedev.ri.
Herald added a subscriber: mcrosier.

https://bugs.llvm.org/show_bug.cgi?id=37778
...shows a miscompile resulting from marking nan builtins as 'const'.

The nan libcalls/builtins take a pointer argument:
http://www.cplusplus.com/reference/cmath/nan-function/
...and the chars dereferenced by that arg are used to fill in the NaN constant 
payload bits.

"const" means that the pointer argument isn't dereferenced. That's translated 
to "readnone" in LLVM.
"pure" means that the pointer argument may be dereferenced. That's translated 
to "readonly" in LLVM.

This change prevents the IR optimizer from killing the lead-up to the nan call 
here:

  double a() {
char buf[4];
buf[0] = buf[1] = buf[2] = '9';
buf[3] = '\0';
return __builtin_nan(buf);
  }

...the optimizer isn't currently able to simplify this to a constant as we 
might hope, but this patch should solve the miscompile.


https://reviews.llvm.org/D48134

Files:
  include/clang/Basic/Builtins.def
  test/CodeGen/math-builtins.c


Index: test/CodeGen/math-builtins.c
===
--- test/CodeGen/math-builtins.c
+++ test/CodeGen/math-builtins.c
@@ -90,25 +90,25 @@
 
   __builtin_nan(c);__builtin_nanf(c);   __builtin_nanl(c); 
__builtin_nanf128(c);
 
-// NO__ERRNO: declare double @nan(i8*) [[READNONE]]
-// NO__ERRNO: declare float @nanf(i8*) [[READNONE]]
-// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
-// NO__ERRNO: declare fp128 @nanf128(i8*) [[READNONE]]
-// HAS_ERRNO: declare double @nan(i8*) [[READNONE:#[0-9]+]]
-// HAS_ERRNO: declare float @nanf(i8*) [[READNONE]]
-// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
-// HAS_ERRNO: declare fp128 @nanf128(i8*) [[READNONE]]
+// NO__ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]]
+// NO__ERRNO: declare float @nanf(i8*) [[PURE]]
+// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]]
+// NO__ERRNO: declare fp128 @nanf128(i8*) [[PURE]]
+// HAS_ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]]
+// HAS_ERRNO: declare float @nanf(i8*) [[PURE]]
+// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]]
+// HAS_ERRNO: declare fp128 @nanf128(i8*) [[PURE]]
 
   __builtin_nans(c);__builtin_nansf(c);   __builtin_nansl(c); 
__builtin_nansf128(c);
 
-// NO__ERRNO: declare double @nans(i8*) [[READNONE]]
-// NO__ERRNO: declare float @nansf(i8*) [[READNONE]]
-// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
-// NO__ERRNO: declare fp128 @nansf128(i8*) [[READNONE]]
-// HAS_ERRNO: declare double @nans(i8*) [[READNONE]]
-// HAS_ERRNO: declare float @nansf(i8*) [[READNONE]]
-// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
-// HAS_ERRNO: declare fp128 @nansf128(i8*) [[READNONE]]
+// NO__ERRNO: declare double @nans(i8*) [[PURE]]
+// NO__ERRNO: declare float @nansf(i8*) [[PURE]]
+// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]]
+// NO__ERRNO: declare fp128 @nansf128(i8*) [[PURE]]
+// HAS_ERRNO: declare double @nans(i8*) [[PURE]]
+// HAS_ERRNO: declare float @nansf(i8*) [[PURE]]
+// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]]
+// HAS_ERRNO: declare fp128 @nansf128(i8*) [[PURE]]
 
   __builtin_pow(f,f);__builtin_powf(f,f);   __builtin_powl(f,f);
 
@@ -188,7 +188,7 @@
 // NO__ERRNO: declare double @cbrt(double) [[READNONE]]
 // NO__ERRNO: declare float @cbrtf(float) [[READNONE]]
 // NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
-// HAS_ERRNO: declare double @cbrt(double) [[READNONE]]
+// HAS_ERRNO: declare double @cbrt(double) [[READNONE:#[0-9]+]]
 // HAS_ERRNO: declare float @cbrtf(float) [[READNONE]]
 // HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
 
@@ -581,9 +581,11 @@
 // NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
 // NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
 // NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
+// NO__ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} }
 
 // HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
 // HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
+// HAS_ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} }
 // HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
 
 // HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
Index: include/clang/Basic/Builtins.def
===
--- include/clang/Basic/Builtins.def
+++ include/clang/Basic/Builtins.def
@@ -137,14 +137,14 @@
 BUILTIN(__builtin_modf , "ddd*"  , "Fn")
 BUILTIN(__builtin_modff, "fff*"  , "Fn")
 BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
-BUILTIN(__builtin_nan,  "dcC*" , "ncF")
-BUILTIN(__builtin_nanf, "fcC*" , "ncF")
-BUILTIN(__builtin_nanl, "LdcC*", "ncF")
-BUILTIN(__builtin_nanf128, "LLdcC*", "ncF")
-BUILTIN(__builtin_nans,  "dcC*" , "ncF")
-BUILTIN(__builtin_nansf, "fcC*" , "ncF")
-BUILTIN(__builtin_nansl, "LdcC*", 

r334619 - [Basic] Fix -Wreorder warning

2018-06-13 Thread Benjamin Kramer via cfe-commits
Author: d0k
Date: Wed Jun 13 09:45:12 2018
New Revision: 334619

URL: http://llvm.org/viewvc/llvm-project?rev=334619=rev
Log:
[Basic] Fix -Wreorder warning

Just use field initializers that don't suffer from this problem

Modified:
cfe/trunk/lib/Basic/Targets/PPC.h

Modified: cfe/trunk/lib/Basic/Targets/PPC.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/PPC.h?rev=334619=334618=334619=diff
==
--- cfe/trunk/lib/Basic/Targets/PPC.h (original)
+++ cfe/trunk/lib/Basic/Targets/PPC.h Wed Jun 13 09:45:12 2018
@@ -49,33 +49,30 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetI
   } ArchDefineTypes;
 
 
-  ArchDefineTypes ArchDefs;
+  ArchDefineTypes ArchDefs = ArchDefineNone;
   static const Builtin::Info BuiltinInfo[];
   static const char *const GCCRegNames[];
   static const TargetInfo::GCCRegAlias GCCRegAliases[];
   std::string CPU;
 
   // Target cpu features.
-  bool HasAltivec;
-  bool HasVSX;
-  bool HasP8Vector;
-  bool HasP8Crypto;
-  bool HasDirectMove;
-  bool HasQPX;
-  bool HasHTM;
-  bool HasBPERMD;
-  bool HasExtDiv;
-  bool HasP9Vector;
+  bool HasAltivec = false;
+  bool HasVSX = false;
+  bool HasP8Vector = false;
+  bool HasP8Crypto = false;
+  bool HasDirectMove = false;
+  bool HasQPX = false;
+  bool HasHTM = false;
+  bool HasBPERMD = false;
+  bool HasExtDiv = false;
+  bool HasP9Vector = false;
 
 protected:
   std::string ABI;
 
 public:
   PPCTargetInfo(const llvm::Triple , const TargetOptions &)
-  : TargetInfo(Triple), HasAltivec(false), HasVSX(false),
-HasP8Vector(false), HasP8Crypto(false), HasDirectMove(false),
-HasQPX(false), HasHTM(false), HasBPERMD(false), HasExtDiv(false),
-HasP9Vector(false), ArchDefs(ArchDefineNone) {
+  : TargetInfo(Triple) {
 SuitableAlign = 128;
 SimdDefaultAlign = 128;
 LongDoubleWidth = LongDoubleAlign = 128;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48036: [CUDA] Make min/max shims host+device.

2018-06-13 Thread Justin Lebar via Phabricator via cfe-commits
jlebar added a comment.

> Last comment in the bug pointed out that those overloads should be constexpr 
> in c++14. Maybe in a separate patch, though.

Yeah, would prefer to do it in a separate patch.  It's possible that having 
constexpr min/max in C++14 mode *without a C++14 standard library* will cause 
problems.  (Don't mean to FUD it -- we should try.  I just would like to be 
able to roll them back separately.  :)


https://reviews.llvm.org/D48036



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35110: [Analyzer] Constraint Manager Negates Difference

2018-06-13 Thread Balogh , Ádám via Phabricator via cfe-commits
baloghadamsoftware added a comment.
Herald added a subscriber: mikhail.ramalho.

Any idea how to proceed?


https://reviews.llvm.org/D35110



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46024: [clang-format] Add SpaceBeforeCpp11BracedList option.

2018-06-13 Thread Ross Kirsling via Phabricator via cfe-commits
rkirsling added a comment.

I'll need someone to commit. Thanks!


Repository:
  rC Clang

https://reviews.llvm.org/D46024



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48027: [analyzer] Improve `CallDescription` to handle c++ method.

2018-06-13 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun added inline comments.



Comment at: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp:32
  check::PostCall> {
-  CallDescription CStrFn;
+  const llvm::SmallVector CStrFnFamily = {
+{"std::basic_string::c_str"}, {"std::basic_string::c_str"},

I am not sure if this is the right solution in case of this check. We should 
track `c_str` calls regardless of what the template parameter is, so supporting 
any instantiation of `basic_string` is desired. This might not be the case, 
however, for other checks. 

If we think it is more likely we do not care about the template arguments, 
maybe a separate API could be used, where we pass the qualified name of the 
class separately without the template arguments.
Alternatively, we could use matches name so the users could use regexps.

At this point I also wonder what isCalled API gives us compared to matchers? 
Maybe it is more convenient to use than calling a `match`. Also, isCalled API 
has an IdentifierInfo cached which could be used for relatively efficient 
checks.

@NoQ what do you think?





Comment at: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp:65
   auto *TypeDecl = TypedR->getValueType()->getAsCXXRecordDecl();
   if (TypeDecl->getName() != "basic_string")
 return;

If we check for fully qualified names, this check might be redundant.



Comment at: lib/StaticAnalyzer/Core/CallEvent.cpp:273
+  auto Matches =
+  match(namedDecl(hasName(CD.FuncName)).bind("match_qualified_name"), *ND,
+LCtx->getAnalysisDeclContext()->getASTContext());

Doesn't match also traverse the subtree of the AST? We only need to check if 
that particular node matches the qualified name. I wonder if we could, during 
the traversal, find another node that is a match unintentionally.


Repository:
  rC Clang

https://reviews.llvm.org/D48027



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48132: [COFF] Add ARM64 intrinsics: __yield, __wfe, __wfi, __sev, __sevl

2018-06-13 Thread Mandeep Singh Grang via Phabricator via cfe-commits
mgrang created this revision.
mgrang added reviewers: mstorsjo, compnerd.
Herald added a reviewer: javed.absar.
Herald added subscribers: chrib, kristof.beyls.

These intrinsics result in hint instructions. They are provided here for MSVC 
ARM64 compatibility.


Repository:
  rC Clang

https://reviews.llvm.org/D48132

Files:
  include/clang/Basic/BuiltinsAArch64.def
  lib/CodeGen/CGBuiltin.cpp
  test/CodeGen/arm64-microsoft-intrinsics.c


Index: test/CodeGen/arm64-microsoft-intrinsics.c
===
--- test/CodeGen/arm64-microsoft-intrinsics.c
+++ test/CodeGen/arm64-microsoft-intrinsics.c
@@ -24,3 +24,38 @@
 
 // CHECK-MSVC: @llvm.aarch64.isb(i32 0)
 // CHECK-LINUX: error: implicit declaration of function '__isb'
+
+void check__yield(void) {
+  __yield();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 1)
+// CHECK-LINUX: error: implicit declaration of function '__yield'
+
+void check__wfe(void) {
+  __wfe();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 2)
+// CHECK-LINUX: error: implicit declaration of function '__wfe'
+
+void check__wfi(void) {
+  __wfi();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 3)
+// CHECK-LINUX: error: implicit declaration of function '__wfi'
+
+void check__sev(void) {
+  __sev();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 4)
+// CHECK-LINUX: error: implicit declaration of function '__sev'
+
+void check__sevl(void) {
+  __sevl();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 5)
+// CHECK-LINUX: error: implicit declaration of function '__sevl'
Index: lib/CodeGen/CGBuiltin.cpp
===
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -6362,18 +6362,23 @@
 HintID = 0;
 break;
   case AArch64::BI__builtin_arm_yield:
+  case AArch64::BI__yield:
 HintID = 1;
 break;
   case AArch64::BI__builtin_arm_wfe:
+  case AArch64::BI__wfe:
 HintID = 2;
 break;
   case AArch64::BI__builtin_arm_wfi:
+  case AArch64::BI__wfi:
 HintID = 3;
 break;
   case AArch64::BI__builtin_arm_sev:
+  case AArch64::BI__sev:
 HintID = 4;
 break;
   case AArch64::BI__builtin_arm_sevl:
+  case AArch64::BI__sevl:
 HintID = 5;
 break;
   }
Index: include/clang/Basic/BuiltinsAArch64.def
===
--- include/clang/Basic/BuiltinsAArch64.def
+++ include/clang/Basic/BuiltinsAArch64.def
@@ -65,9 +65,15 @@
 BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
 BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
 
+// MSVC
 LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
 LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__yield, "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfe,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfi,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__sev,   "v", "",   ALL_MS_LANGUAGES)
+LANGBUILTIN(__sevl,  "v", "",   ALL_MS_LANGUAGES)
 
 // MSVC intrinsics for volatile but non-acquire/release loads and stores
 LANGBUILTIN(__iso_volatile_load8,   "ccCD*", "n", ALL_MS_LANGUAGES)


Index: test/CodeGen/arm64-microsoft-intrinsics.c
===
--- test/CodeGen/arm64-microsoft-intrinsics.c
+++ test/CodeGen/arm64-microsoft-intrinsics.c
@@ -24,3 +24,38 @@
 
 // CHECK-MSVC: @llvm.aarch64.isb(i32 0)
 // CHECK-LINUX: error: implicit declaration of function '__isb'
+
+void check__yield(void) {
+  __yield();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 1)
+// CHECK-LINUX: error: implicit declaration of function '__yield'
+
+void check__wfe(void) {
+  __wfe();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 2)
+// CHECK-LINUX: error: implicit declaration of function '__wfe'
+
+void check__wfi(void) {
+  __wfi();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 3)
+// CHECK-LINUX: error: implicit declaration of function '__wfi'
+
+void check__sev(void) {
+  __sev();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 4)
+// CHECK-LINUX: error: implicit declaration of function '__sev'
+
+void check__sevl(void) {
+  __sevl();
+}
+
+// CHECK-MSVC: @llvm.aarch64.hint(i32 5)
+// CHECK-LINUX: error: implicit declaration of function '__sevl'
Index: lib/CodeGen/CGBuiltin.cpp
===
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -6362,18 +6362,23 @@
 HintID = 0;
 break;
   case AArch64::BI__builtin_arm_yield:
+  case AArch64::BI__yield:
 HintID = 1;
 break;
   case AArch64::BI__builtin_arm_wfe:
+  case AArch64::BI__wfe:
 HintID = 2;
 break;
   case AArch64::BI__builtin_arm_wfi:
+  case AArch64::BI__wfi:
 HintID = 3;
 break;
   case AArch64::BI__builtin_arm_sev:
+  case AArch64::BI__sev:
 HintID = 4;
 break;
   case AArch64::BI__builtin_arm_sevl:
+  case AArch64::BI__sevl:
 HintID = 5;
 break;
   }
Index: include/clang/Basic/BuiltinsAArch64.def

[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents

2018-06-13 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: test/Frontend/fixed_point_bit_widths.c:44
+
+// CHECK-NEXT: @size_SsF  = dso_local global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_SF   = dso_local global i{{[0-9]+}} 4

ebevhan wrote:
> Wait; should these dso_local be `{{.*}}`?
They should, I forgot to get the latest diff which checks this since not all 
targets produce `dso_local`.


Repository:
  rC Clang

https://reviews.llvm.org/D46911



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents

2018-06-13 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 151184.
leonardchan marked an inline comment as done.

Repository:
  rC Clang

https://reviews.llvm.org/D46911

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_bit_widths.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp

Index: test/Frontend/fixed_point_errors.cpp
===
--- test/Frontend/fixed_point_errors.cpp
+++ test/Frontend/fixed_point_errors.cpp
@@ -1,5 +1,9 @@
+// RUN: %clang_cc1 -x c++ %s -verify
 // RUN: %clang_cc1 -x c++ -ffixed-point %s -verify
 
 // Name namgling is not provided for fixed point types in c++
 
 _Accum accum;   // expected-error{{unknown type name '_Accum'}}
+_Fract fract;   // expected-error{{unknown type name '_Fract'}}
+_Sat _Accum sat_accum;  // expected-error{{unknown type name '_Sat'}}
+// expected-error@-1{{expected ';' after top level declarator}}
Index: test/Frontend/fixed_point_errors.c
===
--- test/Frontend/fixed_point_errors.c
+++ test/Frontend/fixed_point_errors.c
@@ -5,6 +5,14 @@
 
 long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
 unsigned long long _Accum u_longlong_accum;   // expected-error{{'long long _Accum' is invalid}}
+long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+unsigned long long _Fract u_longlong_fract;   // expected-error{{'long long _Fract' is invalid}}
+
+_Sat long long _Accum sat_longlong_accum; // expected-error{{'long long _Accum' is invalid}}
+_Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat long long _Fract sat_longlong_fract; // expected-error{{'long long _Fract' is invalid}}
+_Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+
 
 /* Although _Complex types work with floating point numbers, the extension
  * provides no info for complex fixed point types. */
@@ -19,9 +27,67 @@
 _Complex _Accum cmplx_s_accum;  // expected-error{{'_Complex _Accum' is invalid}}
 _Complex long _Accum cmplx_s_long_accum;// expected-error{{'_Complex _Accum' is invalid}}
 
+_Complex signed short _Fract cmplx_s_short_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex signed _Fract cmplx_s_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex signed long _Fract cmplx_s_long_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned short _Fract cmplx_u_short_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned _Fract cmplx_u_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned long _Fract cmplx_u_long_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex short _Fract cmplx_s_short_fract;  // expected-error{{'_Complex _Fract' is invalid}}
+_Complex _Fract cmplx_s_fract;  // expected-error{{'_Complex _Fract' is invalid}}
+_Complex long _Fract cmplx_s_long_fract;// expected-error{{'_Complex _Fract' is invalid}}
+
+_Complex _Sat signed short _Accum cmplx_sat_s_short_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat signed _Accum cmplx_sat_s_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat signed long _Accum cmplx_sat_s_long_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat unsigned short _Accum cmplx_sat_u_short_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat unsigned _Accum cmplx_sat_u_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat unsigned long _Accum cmplx_sat_u_long_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat short _Accum cmplx_sat_s_short_accum;  // expected-error{{'_Complex _Accum' is 

[PATCH] D48088: [PowerPC] The __float128 type should only be available on Power9

2018-06-13 Thread Stefan Pintilie via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC334613: [PowerPC] The __float128 type should only be 
available on Power9 (authored by stefanp, committed by ).
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D48088

Files:
  lib/Basic/Targets/PPC.cpp
  lib/Basic/Targets/PPC.h
  test/Driver/ppc-f128-support-check.c
  test/Preprocessor/init.c
  test/Sema/float128-ld-incompatibility.cpp

Index: test/Driver/ppc-f128-support-check.c
===
--- test/Driver/ppc-f128-support-check.c
+++ test/Driver/ppc-f128-support-check.c
@@ -0,0 +1,20 @@
+// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \
+// RUN:   -mcpu=pwr9 -mfloat128 %s 2>&1 | FileCheck %s --check-prefix=HASF128
+// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \
+// RUN:   -mcpu=power9 -mfloat128 %s 2>&1 | FileCheck %s --check-prefix=HASF128
+
+// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \
+// RUN:   -mcpu=pwr8 -mfloat128 %s 2>&1 | FileCheck %s --check-prefix=NOF128
+// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \
+// RUN:   -mcpu=pwr7 -mfloat128 %s 2>&1 | FileCheck %s --check-prefix=NOF128
+// RUN: not %clang -target powerpc64le-unknown-linux-gnu -fsyntax-only \
+// RUN:   -mfloat128 %s 2>&1 | FileCheck %s --check-prefix=NOF128
+
+#ifdef __FLOAT128__
+static_assert(false, "__float128 enabled");
+#endif
+
+// HASF128: __float128 enabled
+// HASF128-NOT: option '-mfloat128' cannot be specified with
+// NOF128: option '-mfloat128' cannot be specified with
+
Index: test/Preprocessor/init.c
===
--- test/Preprocessor/init.c
+++ test/Preprocessor/init.c
@@ -6370,7 +6370,7 @@
 // PPCPOWER9:#define _ARCH_PWR7 1
 // PPCPOWER9:#define _ARCH_PWR9 1
 //
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +float128 -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-FLOAT128 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +float128 -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-FLOAT128 %s
 // PPC-FLOAT128:#define __FLOAT128__ 1
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-unknown-linux-gnu -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC64-LINUX %s
Index: test/Sema/float128-ld-incompatibility.cpp
===
--- test/Sema/float128-ld-incompatibility.cpp
+++ test/Sema/float128-ld-incompatibility.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 \
-// RUN: -triple powerpc64le-unknown-linux-gnu -target-cpu pwr8 \
+// RUN: -triple powerpc64le-unknown-linux-gnu -target-cpu pwr9 \
 // RUN: -target-feature +float128 %s
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -Wno-parentheses %s
 
Index: lib/Basic/Targets/PPC.h
===
--- lib/Basic/Targets/PPC.h
+++ lib/Basic/Targets/PPC.h
@@ -18,13 +18,38 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/Compiler.h"
 
 namespace clang {
 namespace targets {
 
 // PPC abstract base class
 class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
+
+  /// Flags for architecture specific defines.
+  typedef enum {
+ArchDefineNone = 0,
+ArchDefineName = 1 << 0, //  is substituted for arch name.
+ArchDefinePpcgr = 1 << 1,
+ArchDefinePpcsq = 1 << 2,
+ArchDefine440 = 1 << 3,
+ArchDefine603 = 1 << 4,
+ArchDefine604 = 1 << 5,
+ArchDefinePwr4 = 1 << 6,
+ArchDefinePwr5 = 1 << 7,
+ArchDefinePwr5x = 1 << 8,
+ArchDefinePwr6 = 1 << 9,
+ArchDefinePwr6x = 1 << 10,
+ArchDefinePwr7 = 1 << 11,
+ArchDefinePwr8 = 1 << 12,
+ArchDefinePwr9 = 1 << 13,
+ArchDefineA2 = 1 << 14,
+ArchDefineA2q = 1 << 15
+  } ArchDefineTypes;
+
+
+  ArchDefineTypes ArchDefs;
   static const Builtin::Info BuiltinInfo[];
   static const char *const GCCRegNames[];
   static const TargetInfo::GCCRegAlias GCCRegAliases[];
@@ -50,34 +75,13 @@
   : TargetInfo(Triple), HasAltivec(false), HasVSX(false),
 HasP8Vector(false), HasP8Crypto(false), HasDirectMove(false),
 HasQPX(false), HasHTM(false), HasBPERMD(false), HasExtDiv(false),
-HasP9Vector(false) {
+HasP9Vector(false), ArchDefs(ArchDefineNone) {
 SuitableAlign = 128;
 SimdDefaultAlign = 128;
 LongDoubleWidth = LongDoubleAlign = 128;
 LongDoubleFormat = ::APFloat::PPCDoubleDouble();
   }
 
-  /// Flags for architecture specific defines.
-  typedef enum {
-ArchDefineNone = 0,
-ArchDefineName = 1 << 0, //  is substituted 

r334613 - [PowerPC] The __float128 type should only be available on Power9

2018-06-13 Thread Stefan Pintilie via cfe-commits
Author: stefanp
Date: Wed Jun 13 09:05:05 2018
New Revision: 334613

URL: http://llvm.org/viewvc/llvm-project?rev=334613=rev
Log:
[PowerPC] The __float128 type should only be available on Power9

Diasble the use of the type __float128 for PPC machines older
than Power9.

The use of -mfloat128 for PPC machine older than Power9 will result
in an error.

Differential Revision: https://reviews.llvm.org/D48088

Added:
cfe/trunk/test/Driver/ppc-f128-support-check.c
Modified:
cfe/trunk/lib/Basic/Targets/PPC.cpp
cfe/trunk/lib/Basic/Targets/PPC.h
cfe/trunk/test/Preprocessor/init.c
cfe/trunk/test/Sema/float128-ld-incompatibility.cpp

Modified: cfe/trunk/lib/Basic/Targets/PPC.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/PPC.cpp?rev=334613=334612=334613=diff
==
--- cfe/trunk/lib/Basic/Targets/PPC.cpp (original)
+++ cfe/trunk/lib/Basic/Targets/PPC.cpp Wed Jun 13 09:05:05 2018
@@ -15,7 +15,6 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/MacroBuilder.h"
 #include "clang/Basic/TargetBuiltins.h"
-#include "llvm/ADT/StringSwitch.h"
 
 using namespace clang;
 using namespace clang::targets;
@@ -116,111 +115,37 @@ void PPCTargetInfo::getTargetDefines(con
   (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64))
 Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
 
-  // CPU identification.
-  ArchDefineTypes defs =
-  (ArchDefineTypes)llvm::StringSwitch(CPU)
-  .Case("440", ArchDefineName)
-  .Case("450", ArchDefineName | ArchDefine440)
-  .Case("601", ArchDefineName)
-  .Case("602", ArchDefineName | ArchDefinePpcgr)
-  .Case("603", ArchDefineName | ArchDefinePpcgr)
-  .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
-  .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
-  .Case("604", ArchDefineName | ArchDefinePpcgr)
-  .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr)
-  .Case("620", ArchDefineName | ArchDefinePpcgr)
-  .Case("630", ArchDefineName | ArchDefinePpcgr)
-  .Case("7400", ArchDefineName | ArchDefinePpcgr)
-  .Case("7450", ArchDefineName | ArchDefinePpcgr)
-  .Case("750", ArchDefineName | ArchDefinePpcgr)
-  .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr |
-   ArchDefinePpcsq)
-  .Case("a2", ArchDefineA2)
-  .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q)
-  .Case("pwr3", ArchDefinePpcgr)
-  .Case("pwr4", ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq)
-  .Case("pwr5", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr |
-ArchDefinePpcsq)
-  .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4 |
- ArchDefinePpcgr | ArchDefinePpcsq)
-  .Case("pwr6", ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5 |
-ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
-  .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x |
- ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr 
|
- ArchDefinePpcsq)
-  .Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6 |
-ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
-ArchDefinePpcgr | ArchDefinePpcsq)
-  .Case("pwr8", ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x |
-ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
-ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
-  .Case("pwr9", ArchDefineName | ArchDefinePwr8 | ArchDefinePwr7 |
-ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x 
|
-ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
-ArchDefinePpcsq)
-  .Case("power3", ArchDefinePpcgr)
-  .Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
-  .Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
-  ArchDefinePpcsq)
-  .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
-   ArchDefinePpcgr | ArchDefinePpcsq)
-  .Case("power6", ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
-  ArchDefinePwr4 | ArchDefinePpcgr |
-  ArchDefinePpcsq)
-  .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x |
-   ArchDefinePwr5 | ArchDefinePwr4 |
-   ArchDefinePpcgr | ArchDefinePpcsq)
-  .Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 |
-  

r334612 - [libclang] Make c-index-test.c ISO C90 compliant.

2018-06-13 Thread Matt Morehouse via cfe-commits
Author: morehouse
Date: Wed Jun 13 09:00:39 2018
New Revision: 334612

URL: http://llvm.org/viewvc/llvm-project?rev=334612=rev
Log:
[libclang] Make c-index-test.c ISO C90 compliant.

Fixes a build bot breakage caused by r334593.

Modified:
cfe/trunk/tools/c-index-test/c-index-test.c

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=334612=334611=334612=diff
==
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Wed Jun 13 09:00:39 2018
@@ -2304,6 +2304,7 @@ static void print_completion_result(CXTr
   CXString BriefComment;
   CXString Annotation;
   const char *BriefCommentCString;
+  unsigned i;
   
   fprintf(file, "%s:", clang_getCString(ks));
   clang_disposeString(ks);
@@ -2365,7 +2366,6 @@ static void print_completion_result(CXTr
   }
   clang_disposeString(BriefComment);
 
-  unsigned i;
   for (i = 0; i < clang_getCompletionNumFixIts(completion_results, index);
++i) {
 CXSourceRange correction_range;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46915: [Fixed Point Arithmetic] Fixed Point Precision Bits and Fixed Point Literals

2018-06-13 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: lib/AST/ExprConstant.cpp:9437
+  }
+  return Success(-Value, E);
+}

This looks very suspect to me as well... This might not respect padding on 
types whose sign bit is not the MSB, such as _Fract. The same goes for the 
overflow check above.

I think it's quite important that we define the semantics of what padding bits 
should contain. Probably zeroes for unsigned types and a sexted sign bit for 
signed types.


Repository:
  rC Clang

https://reviews.llvm.org/D46915



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45679: [clang-tidy] Add ExprMutationAnalyzer, that analyzes whether an expression is mutated within a statement.

2018-06-13 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman reopened this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

I had to revert due to failing tests. The revert was done in r334606 and this 
is an example of a failing bot: 
http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast/builds/31500


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D45679



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47935: [clangd] Boost completion score according to file proximity.

2018-06-13 Thread Eric Liu via Phabricator via cfe-commits
ioeric updated this revision to Diff 151172.
ioeric added a comment.

- Rebased.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D47935

Files:
  clangd/CodeComplete.cpp
  clangd/FindSymbols.cpp
  clangd/Quality.cpp
  clangd/Quality.h
  unittests/clangd/QualityTests.cpp
  unittests/clangd/TestFS.cpp
  unittests/clangd/URITests.cpp

Index: unittests/clangd/URITests.cpp
===
--- unittests/clangd/URITests.cpp
+++ unittests/clangd/URITests.cpp
@@ -14,46 +14,20 @@
 
 namespace clang {
 namespace clangd {
+
+// Force the unittest URI scheme to be linked,
+extern volatile int UnittestSchemeAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED UnittestSchemeAnchorDest =
+UnittestSchemeAnchorSource;
+
 namespace {
 
 using ::testing::AllOf;
 
 MATCHER_P(Scheme, S, "") { return arg.scheme() == S; }
 MATCHER_P(Authority, A, "") { return arg.authority() == A; }
 MATCHER_P(Body, B, "") { return arg.body() == B; }
 
-// Assume all files in the schema have a "test-root/" root directory, and the
-// schema path is the relative path to the root directory.
-// So the schema of "/some-dir/test-root/x/y/z" is "test:x/y/z".
-class TestScheme : public URIScheme {
-public:
-  static const char *Scheme;
-
-  static const char *TestRoot;
-
-  llvm::Expected
-  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
-  llvm::StringRef HintPath) const override {
-auto Pos = HintPath.find(TestRoot);
-assert(Pos != llvm::StringRef::npos);
-return (HintPath.substr(0, Pos + llvm::StringRef(TestRoot).size()) + Body)
-.str();
-  }
-
-  llvm::Expected
-  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
-auto Pos = AbsolutePath.find(TestRoot);
-assert(Pos != llvm::StringRef::npos);
-return URI(Scheme, /*Authority=*/"",
-   AbsolutePath.substr(Pos + llvm::StringRef(TestRoot).size()));
-  }
-};
-
-const char *TestScheme::Scheme = "unittest";
-const char *TestScheme::TestRoot = "/test-root/";
-
-static URISchemeRegistry::Add X(TestScheme::Scheme, "Test schema");
-
 std::string createOrDie(llvm::StringRef AbsolutePath,
 llvm::StringRef Scheme = "file") {
   auto Uri = URI::create(AbsolutePath, Scheme);
Index: unittests/clangd/TestFS.cpp
===
--- unittests/clangd/TestFS.cpp
+++ unittests/clangd/TestFS.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 #include "TestFS.h"
+#include "URI.h"
 #include "llvm/Support/Errc.h"
 #include "gtest/gtest.h"
 
@@ -62,5 +63,50 @@
   return Path.str();
 }
 
+// Assume all files in the schema have a "test-root/" root directory, and the
+// schema path is the relative path to the root directory.
+// So the schema of "/some-dir/test-root/x/y/z" is "test:x/y/z".
+class TestScheme : public URIScheme {
+public:
+  static const char *Scheme;
+
+  static const char *TestRoot;
+
+  llvm::Expected
+  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
+  llvm::StringRef HintPath) const override {
+auto Pos = HintPath.find(TestRoot);
+assert(Pos != llvm::StringRef::npos);
+return (HintPath.substr(0, Pos + llvm::StringRef(TestRoot).size()) + Body)
+.str();
+  }
+
+  llvm::Expected
+  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
+auto Pos = AbsolutePath.find(TestRoot);
+if (Pos == llvm::StringRef::npos)
+  return llvm::make_error(
+  llvm::Twine("Directory ") + TestRoot + " not found in path " +
+  AbsolutePath,
+  llvm::inconvertibleErrorCode());
+
+return URI(Scheme, /*Authority=*/"",
+   AbsolutePath.substr(Pos + llvm::StringRef(TestRoot).size()));
+  }
+};
+
+const char *TestScheme::Scheme = "unittest";
+#ifdef _WIN32
+const char *TestScheme::TestRoot = "\\test-root\\";
+#else
+const char *TestScheme::TestRoot = "/test-root/";
+#endif
+
+static URISchemeRegistry::Add X(TestScheme::Scheme, "Test schema");
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the plugin.
+volatile int UnittestSchemeAnchorSource = 0;
+
 } // namespace clangd
 } // namespace clang
Index: unittests/clangd/QualityTests.cpp
===
--- unittests/clangd/QualityTests.cpp
+++ unittests/clangd/QualityTests.cpp
@@ -18,12 +18,19 @@
 //===--===//
 
 #include "Quality.h"
+#include "TestFS.h"
 #include "TestTU.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 namespace clang {
 namespace clangd {
+
+// Force the unittest URI scheme to be linked,
+extern volatile int UnittestSchemeAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED UnittestSchemeAnchorDest =
+UnittestSchemeAnchorSource;
+
 namespace {
 
 TEST(QualityTests, 

[clang-tools-extra] r334606 - Reverting r334604 due to failing tests.

2018-06-13 Thread Aaron Ballman via cfe-commits
Author: aaronballman
Date: Wed Jun 13 08:02:34 2018
New Revision: 334606

URL: http://llvm.org/viewvc/llvm-project?rev=334606=rev
Log:
Reverting r334604 due to failing tests.

http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast/builds/31500

Removed:
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.h
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt?rev=334606=334605=334606=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt Wed Jun 13 08:02:34 
2018
@@ -3,7 +3,6 @@ set(LLVM_LINK_COMPONENTS support)
 add_clang_library(clangTidyUtils
   ASTUtils.cpp
   DeclRefExprUtils.cpp
-  ExprMutationAnalyzer.cpp
   ExprSequence.cpp
   FixItHintUtils.cpp
   HeaderFileExtensionsUtils.cpp

Removed: clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp?rev=334605=auto
==
--- clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp (removed)
@@ -1,261 +0,0 @@
-//===-- ExprMutationAnalyzer.cpp - clang-tidy 
-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--===//
-#include "ExprMutationAnalyzer.h"
-
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "llvm/ADT/STLExtras.h"
-
-namespace clang {
-namespace tidy {
-namespace utils {
-using namespace ast_matchers;
-
-namespace {
-
-AST_MATCHER_P(LambdaExpr, hasCaptureInit, const Expr *, E) {
-  return llvm::is_contained(Node.capture_inits(), E);
-}
-
-AST_MATCHER_P(CXXForRangeStmt, hasRangeStmt,
-  ast_matchers::internal::Matcher, InnerMatcher) {
-  const DeclStmt *const Range = Node.getRangeStmt();
-  return InnerMatcher.matches(*Range, Finder, Builder);
-}
-
-const ast_matchers::internal::VariadicDynCastAllOfMatcher
-cxxTypeidExpr;
-
-AST_MATCHER(CXXTypeidExpr, isPotentiallyEvaluated) {
-  return Node.isPotentiallyEvaluated();
-}
-
-const ast_matchers::internal::VariadicDynCastAllOfMatcher
-cxxNoexceptExpr;
-
-const ast_matchers::internal::VariadicDynCastAllOfMatcher
-genericSelectionExpr;
-
-AST_MATCHER_P(GenericSelectionExpr, hasControllingExpr,
-  ast_matchers::internal::Matcher, InnerMatcher) {
-  return InnerMatcher.matches(*Node.getControllingExpr(), Finder, Builder);
-}
-
-const auto nonConstReferenceType = [] {
-  return referenceType(pointee(unless(isConstQualified(;
-};
-
-} // namespace
-
-const Stmt *ExprMutationAnalyzer::findMutation(const Expr *Exp) {
-  const auto Memoized = Results.find(Exp);
-  if (Memoized != Results.end())
-return Memoized->second;
-
-  if (isUnevaluated(Exp))
-return Results[Exp] = nullptr;
-
-  for (const auto  : {::findDirectMutation,
- ::findMemberMutation,
- ::findArrayElementMutation,
- ::findCastMutation,
- ::findRangeLoopMutation,
- ::findReferenceMutation}) {
-if (const Stmt *S = (this->*Finder)(Exp))
-  return Results[Exp] = S;
-  }
-
-  return Results[Exp] = nullptr;
-}
-
-bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) {
-  return selectFirst(
- "expr",
- match(
- findAll(
- expr(equalsNode(Exp),
-  anyOf(
-  // `Exp` is part of the underlying expression of
-  // decltype/typeof if it has an ancestor of
-  // typeLoc.
-  hasAncestor(typeLoc(unless(
-  hasAncestor(unaryExprOrTypeTraitExpr(),
-  hasAncestor(expr(anyOf(
-  // `UnaryExprOrTypeTraitExpr` is unevaluated
-  // unless it's sizeof on VLA.
-  unaryExprOrTypeTraitExpr(unless(sizeOfExpr(
-  
hasArgumentOfType(variableArrayType(),
-  // 

[PATCH] D47935: [clangd] Boost completion score according to file proximity.

2018-06-13 Thread Eric Liu via Phabricator via cfe-commits
ioeric added a comment.

In https://reviews.llvm.org/D47935#1129987, @sammccall wrote:

> Sorry for the delay on this change. There's a bunch of complexity in this 
> problem that I haven't seen how to slice through:
>
> 1. the signals needed seem like a weird fit for the Symbol*Signals structs 
> for some reason (maybe my misdesign)


According to offline discussion, I added a structure  `SymbolRelevanceContext`  
that captures per-query signals like proximity paths. Not sure about the name 
though.

> 2. the inconsistency between how we do this for Sema and for Index results 
> has... only slightly good reasons

The proximity scores for index and sema are now explicitly separated to make it 
easier to understand and debug.

> 3. the URI vs filename thing is awkward
> 4. with all this, the actual scoring still seems ad-hoc and is missing 
> important parts (main header, transitive includes)
> 
>   Not all your fault that the code reflects this, the problem is tangly. But 
> it's hard for me to reason about APIs or performance or layering.
> 
>   Looking at the last point (scoring model) because it seems the most 
> tractable. I think this is basically an edit distance problem? (We can call 
> the result "proximity", start at one, and multiply by <1, or call it 
> "distance" and start at 0 and add penalties, but it's equivalent).
> 5. we're computing distances between files (glossing over URI-space vs 
> file-space)
> 6. the roots are the main file, and maybe the matching header
> 7. edits take us from a filepath to a related filepath:
>   - from a file to a header it `#include`s
>   - from a file to its parent directory
>   - from a parent directory to a child directory
>   - from a parent directory to a file in it
> 8. the distance is the smallest sum-of-penalties for any path leading from 
> the root to the symbol
> 
>   What do you think of this model?
> 
>   
> 
>   **If** the model seems reasonable, then it suggests an approach of building 
> a one-per-query data structure that computes the needed edit-distance 
> recursively, memoizing results. `SymbolRelevanceResults` could store the 
> symbol path and a pointer to the edit-distance machine, and for debugging the 
> machine would know how to describe its configuration. URI/path mapping 
> wouldn't be a performance concern (I think) if the memoization captured it.

I like how this model addresses the proximity for src/ and include/ setup. I 
think we could start with something simple and iterate, although I agree that 
we should strike for a design that would be easy to replace the proximity 
algorithm in the future.

> Let's chat offline?




Comment at: clangd/Quality.cpp:171
+/// "uri:///a/b/c" will be treated as /a/b/c
+static float uriProximity(StringRef UX, StringRef UY) {
+  auto SchemeSplitX = UX.split(':');

sammccall wrote:
> ioeric wrote:
> > sammccall wrote:
> > > This doesn't look quite right to me.
> > > We can tune the details later, but in practice this seems like it's 
> > > *very* hard to get zero proximity, which is our neutral score - you need 
> > > to be 18 directories away?
> > > 
> > > FWIW, fozzie appears to give an additive boost proportional to 5-up, 
> > > where up is the number of directories from the context you have to 
> > > traverse up from the context to get to a parent of the symbol. (There's 
> > > no penalty for down-traversals probably for implementation reasons, this 
> > > should be smaller than the up-traversal penalty I think)
> > The numbers are guessed... definitely happy to tune.
> > > We can tune the details later, but in practice this seems like it's 
> > > *very* hard to get zero proximity, which is our neutral score - you need 
> > > to be 18 directories away?
> > It's 18 directories away if one file is in an ancestor directories of the 
> > other (i.e. only traverse up or down). If you need to traverse up and down, 
> > the penalty for each directory is 0.1, which takes 10 directories (up+down, 
> > so 
> > 5 up in average). I think it's useful to make this distinction because I 
> > think it's more likely for a file to use a header if it's in the file path. 
> >  
> > 
> > I'm not sure if we should use zero as the neutral score. For example, if a 
> > codebase has deep directory structure, most scores are probably going to be 
> > small; conversely, most scores would be relatively big. I think relative 
> > scores are more useful.
> > 
> > > (There's no penalty for down-traversals probably for implementation 
> > > reasons, this should be smaller than the up-traversal penalty I think)
> > Why do you think down-traversal should take less penalty?
> > 
> > If you need to traverse up and down, the penalty for each directory is 0.1, 
> > which takes 10 directories (up+down, so 5 up in average).
> I think you've halved twice there - it still seems to be 10, which is a lot.
> 
> > I'm not sure if we should use zero as the neutral score.
> Well, zero is currently the 

[PATCH] D47935: [clangd] Boost completion score according to file proximity.

2018-06-13 Thread Eric Liu via Phabricator via cfe-commits
ioeric updated this revision to Diff 151169.
ioeric added a comment.

- Introduced a one-per-query structure for relevance signals; use 
multiplication for proximity; simplify tests a bit; separate index and sema 
proximity scores.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D47935

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/CodeComplete.cpp
  clangd/FindSymbols.cpp
  clangd/Quality.cpp
  clangd/Quality.h
  clangd/index/FileIndex.cpp
  clangd/index/FileIndex.h
  unittests/clangd/ClangdTests.cpp
  unittests/clangd/FileIndexTests.cpp
  unittests/clangd/QualityTests.cpp
  unittests/clangd/TestFS.cpp
  unittests/clangd/URITests.cpp

Index: unittests/clangd/URITests.cpp
===
--- unittests/clangd/URITests.cpp
+++ unittests/clangd/URITests.cpp
@@ -14,46 +14,20 @@
 
 namespace clang {
 namespace clangd {
+
+// Force the unittest URI scheme to be linked,
+extern volatile int UnittestSchemeAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED UnittestSchemeAnchorDest =
+UnittestSchemeAnchorSource;
+
 namespace {
 
 using ::testing::AllOf;
 
 MATCHER_P(Scheme, S, "") { return arg.scheme() == S; }
 MATCHER_P(Authority, A, "") { return arg.authority() == A; }
 MATCHER_P(Body, B, "") { return arg.body() == B; }
 
-// Assume all files in the schema have a "test-root/" root directory, and the
-// schema path is the relative path to the root directory.
-// So the schema of "/some-dir/test-root/x/y/z" is "test:x/y/z".
-class TestScheme : public URIScheme {
-public:
-  static const char *Scheme;
-
-  static const char *TestRoot;
-
-  llvm::Expected
-  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
-  llvm::StringRef HintPath) const override {
-auto Pos = HintPath.find(TestRoot);
-assert(Pos != llvm::StringRef::npos);
-return (HintPath.substr(0, Pos + llvm::StringRef(TestRoot).size()) + Body)
-.str();
-  }
-
-  llvm::Expected
-  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
-auto Pos = AbsolutePath.find(TestRoot);
-assert(Pos != llvm::StringRef::npos);
-return URI(Scheme, /*Authority=*/"",
-   AbsolutePath.substr(Pos + llvm::StringRef(TestRoot).size()));
-  }
-};
-
-const char *TestScheme::Scheme = "unittest";
-const char *TestScheme::TestRoot = "/test-root/";
-
-static URISchemeRegistry::Add X(TestScheme::Scheme, "Test schema");
-
 std::string createOrDie(llvm::StringRef AbsolutePath,
 llvm::StringRef Scheme = "file") {
   auto Uri = URI::create(AbsolutePath, Scheme);
Index: unittests/clangd/TestFS.cpp
===
--- unittests/clangd/TestFS.cpp
+++ unittests/clangd/TestFS.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 #include "TestFS.h"
+#include "URI.h"
 #include "llvm/Support/Errc.h"
 #include "gtest/gtest.h"
 
@@ -62,5 +63,50 @@
   return Path.str();
 }
 
+// Assume all files in the schema have a "test-root/" root directory, and the
+// schema path is the relative path to the root directory.
+// So the schema of "/some-dir/test-root/x/y/z" is "test:x/y/z".
+class TestScheme : public URIScheme {
+public:
+  static const char *Scheme;
+
+  static const char *TestRoot;
+
+  llvm::Expected
+  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
+  llvm::StringRef HintPath) const override {
+auto Pos = HintPath.find(TestRoot);
+assert(Pos != llvm::StringRef::npos);
+return (HintPath.substr(0, Pos + llvm::StringRef(TestRoot).size()) + Body)
+.str();
+  }
+
+  llvm::Expected
+  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
+auto Pos = AbsolutePath.find(TestRoot);
+if (Pos == llvm::StringRef::npos)
+  return llvm::make_error(
+  llvm::Twine("Directory ") + TestRoot + " not found in path " +
+  AbsolutePath,
+  llvm::inconvertibleErrorCode());
+
+return URI(Scheme, /*Authority=*/"",
+   AbsolutePath.substr(Pos + llvm::StringRef(TestRoot).size()));
+  }
+};
+
+const char *TestScheme::Scheme = "unittest";
+#ifdef _WIN32
+const char *TestScheme::TestRoot = "\\test-root\\";
+#else
+const char *TestScheme::TestRoot = "/test-root/";
+#endif
+
+static URISchemeRegistry::Add X(TestScheme::Scheme, "Test schema");
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the plugin.
+volatile int UnittestSchemeAnchorSource = 0;
+
 } // namespace clangd
 } // namespace clang
Index: unittests/clangd/QualityTests.cpp
===
--- unittests/clangd/QualityTests.cpp
+++ unittests/clangd/QualityTests.cpp
@@ -18,12 +18,19 @@
 //===--===//
 
 #include "Quality.h"
+#include "TestFS.h"
 #include "TestTU.h"
 

[PATCH] D47578: Do not enforce absolute path argv0 in windows

2018-06-13 Thread Takuto Ikuta via Phabricator via cfe-commits
takuto.ikuta added a comment.

Thank you!


https://reviews.llvm.org/D47578



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48027: [analyzer] Improve `CallDescription` to handle c++ method.

2018-06-13 Thread Henry Wong via Phabricator via cfe-commits
MTC updated this revision to Diff 151166.
MTC added a comment.

- Use `hasName` matcher to match the qualified name.
- Use the full name, like `std::basic_string::c_str` instead of `c_str` 
to match the `c_str` method in `DanglingInternalBufferChecker.cpp`.




Repository:
  rC Clang

https://reviews.llvm.org/D48027

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
  lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
  lib/StaticAnalyzer/Core/CallEvent.cpp

Index: lib/StaticAnalyzer/Core/CallEvent.cpp
===
--- lib/StaticAnalyzer/Core/CallEvent.cpp
+++ lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -28,6 +28,7 @@
 #include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/ProgramPoint.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/CrossTU/CrossTranslationUnit.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
@@ -65,6 +66,7 @@
 
 using namespace clang;
 using namespace ento;
+using namespace clang::ast_matchers;
 
 QualType CallEvent::getResultType() const {
   ASTContext  = getState()->getStateManager().getContext();
@@ -256,11 +258,24 @@
 return false;
   if (!CD.IsLookupDone) {
 CD.IsLookupDone = true;
-CD.II = ()->getStateManager().getContext().Idents.get(CD.FuncName);
+CD.II = ()->getStateManager().getContext().Idents.get(
+CD.getFunctionName());
   }
   const IdentifierInfo *II = getCalleeIdentifier();
   if (!II || II != CD.II)
 return false;
+
+  const NamedDecl *ND = dyn_cast_or_null(getDecl());
+  if (!ND)
+return false;
+
+  auto Matches =
+  match(namedDecl(hasName(CD.FuncName)).bind("match_qualified_name"), *ND,
+LCtx->getAnalysisDeclContext()->getASTContext());
+
+  if (Matches.empty())
+return false;
+
   return (CD.RequiredArgs == CallDescription::NoArgRequirement ||
   CD.RequiredArgs == getNumArgs());
 }
Index: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
+++ lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
@@ -13,26 +13,28 @@
 //
 //===--===//
 
+#include "AllocationState.h"
 #include "ClangSACheckers.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "AllocationState.h"
+#include "llvm/ADT/SmallVector.h"
 
 using namespace clang;
 using namespace ento;
 
 namespace {
 
 class DanglingInternalBufferChecker : public Checker {
-  CallDescription CStrFn;
+  const llvm::SmallVector CStrFnFamily = {
+{"std::basic_string::c_str"}, {"std::basic_string::c_str"},
+{"std::basic_string::c_str"},
+{"std::basic_string::c_str"}};
 
 public:
-  DanglingInternalBufferChecker() : CStrFn("c_str") {}
-
   /// Record the connection between the symbol returned by c_str() and the
   /// corresponding string object region in the ProgramState. Mark the symbol
   /// released if the string object is destroyed.
@@ -65,7 +67,15 @@
 
   ProgramStateRef State = C.getState();
 
-  if (Call.isCalled(CStrFn)) {
+  auto isCStrFnFamilyCall = [&](const CallEvent ) -> bool {
+for (auto CStrFn : CStrFnFamily) {
+  if (Call.isCalled(CStrFn))
+return true;
+}
+return false;
+  };
+
+  if (isCStrFnFamilyCall(Call)) {
 SVal RawPtr = Call.getReturnValue();
 if (!RawPtr.isUnknown()) {
   State = State->set(TypedR, RawPtr.getAsSymbol());
Index: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -79,6 +79,7 @@
 
   mutable IdentifierInfo *II = nullptr;
   mutable bool IsLookupDone = false;
+  // Represent the function name or method name, like "X" or "a::b::X".
   StringRef FuncName;
   unsigned RequiredArgs;
 
@@ -96,7 +97,11 @@
   : FuncName(FuncName), RequiredArgs(RequiredArgs) {}
 
   /// Get the name of the function that this object matches.
-  StringRef getFunctionName() const { return FuncName; }
+  StringRef getFunctionName() const {
+auto QualifierNamePair = FuncName.rsplit("::");
+return QualifierNamePair.second.empty() ? QualifierNamePair.first
+: QualifierNamePair.second;
+  }
 };
 
 template
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45679: [clang-tidy] Add ExprMutationAnalyzer, that analyzes whether an expression is mutated within a statement.

2018-06-13 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman closed this revision.
aaron.ballman added a comment.

I've commit in r334604 with one minor change -- I added an include for  
to the unit test so that `std::isspace()` would compile properly on all 
platforms.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D45679



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r334604 - Add a new class to analyze whether an expression is mutated within a statement.

2018-06-13 Thread Aaron Ballman via cfe-commits
Author: aaronballman
Date: Wed Jun 13 07:41:42 2018
New Revision: 334604

URL: http://llvm.org/viewvc/llvm-project?rev=334604=rev
Log:
Add a new class to analyze whether an expression is mutated within a statement.

ExprMutationAnalyzer is a generally useful helper that can be used in different 
clang-tidy checks for checking whether a given expression is (potentially) 
mutated within a statement (typically the enclosing compound statement.) This 
is a more general and more powerful/accurate version of isOnlyUsedAsConst, 
which is used in ForRangeCopyCheck, UnnecessaryCopyInitialization.

Patch by Shuai Wang

Added:
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.h
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt?rev=334604=334603=334604=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt Wed Jun 13 07:41:42 
2018
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support)
 add_clang_library(clangTidyUtils
   ASTUtils.cpp
   DeclRefExprUtils.cpp
+  ExprMutationAnalyzer.cpp
   ExprSequence.cpp
   FixItHintUtils.cpp
   HeaderFileExtensionsUtils.cpp

Added: clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp?rev=334604=auto
==
--- clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp Wed Jun 
13 07:41:42 2018
@@ -0,0 +1,261 @@
+//===-- ExprMutationAnalyzer.cpp - clang-tidy 
-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+#include "ExprMutationAnalyzer.h"
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "llvm/ADT/STLExtras.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+using namespace ast_matchers;
+
+namespace {
+
+AST_MATCHER_P(LambdaExpr, hasCaptureInit, const Expr *, E) {
+  return llvm::is_contained(Node.capture_inits(), E);
+}
+
+AST_MATCHER_P(CXXForRangeStmt, hasRangeStmt,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  const DeclStmt *const Range = Node.getRangeStmt();
+  return InnerMatcher.matches(*Range, Finder, Builder);
+}
+
+const ast_matchers::internal::VariadicDynCastAllOfMatcher
+cxxTypeidExpr;
+
+AST_MATCHER(CXXTypeidExpr, isPotentiallyEvaluated) {
+  return Node.isPotentiallyEvaluated();
+}
+
+const ast_matchers::internal::VariadicDynCastAllOfMatcher
+cxxNoexceptExpr;
+
+const ast_matchers::internal::VariadicDynCastAllOfMatcher
+genericSelectionExpr;
+
+AST_MATCHER_P(GenericSelectionExpr, hasControllingExpr,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  return InnerMatcher.matches(*Node.getControllingExpr(), Finder, Builder);
+}
+
+const auto nonConstReferenceType = [] {
+  return referenceType(pointee(unless(isConstQualified(;
+};
+
+} // namespace
+
+const Stmt *ExprMutationAnalyzer::findMutation(const Expr *Exp) {
+  const auto Memoized = Results.find(Exp);
+  if (Memoized != Results.end())
+return Memoized->second;
+
+  if (isUnevaluated(Exp))
+return Results[Exp] = nullptr;
+
+  for (const auto  : {::findDirectMutation,
+ ::findMemberMutation,
+ ::findArrayElementMutation,
+ ::findCastMutation,
+ ::findRangeLoopMutation,
+ ::findReferenceMutation}) {
+if (const Stmt *S = (this->*Finder)(Exp))
+  return Results[Exp] = S;
+  }
+
+  return Results[Exp] = nullptr;
+}
+
+bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) {
+  return selectFirst(
+ "expr",
+ match(
+ findAll(
+ expr(equalsNode(Exp),
+  anyOf(
+  // `Exp` is part of the underlying expression of
+  // decltype/typeof if it has an ancestor of
+  // typeLoc.
+  hasAncestor(typeLoc(unless(
+  hasAncestor(unaryExprOrTypeTraitExpr(),
+  

[PATCH] D47578: Do not enforce absolute path argv0 in windows

2018-06-13 Thread Hans Wennborg via Phabricator via cfe-commits
hans added a comment.

In https://reviews.llvm.org/D47578#1127749, @takuto.ikuta wrote:

> Rui-san, can I ask you to merge this?


Committed here: 
http://llvm.org/viewvc/llvm-project?view=revision=334602


https://reviews.llvm.org/D47578



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >