[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-02-09 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

I will pick up the changes later next week.




Comment at: include/charconv:89
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum class _LIBCPP_ENUM_VIS chars_format

EricWF wrote:
> We need to hide these names when `_LIBCPP_STD_VER < 17`, since we're not 
> allowed to introduce new names into namespace `std` in older dialects.
But this header is backported to C++11, so I intended to not to guard it.



Comment at: include/charconv:122
+template 
+inline _LIBCPP_INLINE_VISIBILITY auto
+__to_unsigned(_Tp __x) -> typename make_unsigned<_Tp>::type

EricWF wrote:
> Same as above. There's no reason to deviate from the typical libc++ style and 
> use trailing return types here.
libc++ doesn't have one uniformed style.  For some reason I found this style 
formats better with clang-format.



Comment at: include/charconv:151
+
+#if __has_builtin(__builtin_clzll)
+if (__tx::digits <= __diff || __tx::width(__value) <= __diff)

EricWF wrote:
> `` already has a `__clz` wrapper for `__builtin_clz` et al. We 
> should use that instead. That also allows us to get rid of the fallback 
> implementation, and it correctly uses the builtin for compilers like GCC 
> which don't provide `__has_builtin`.
I saw that, and I agree this can be improved, however `` would be 
too heavy to include here.  Thoughts?



Comment at: include/support/itoa/itoa.h:81
+#if __has_builtin(__builtin_clzll)
+static _LIBCPP_INLINE_VISIBILITY auto width(_Tp __v) -> int
+{

EricWF wrote:
> `width`, `convert` and `pow` need to be reserved names.
These names are standard names (functions), so users can't provide function 
style macros to override them.  Am I wrong on that?



Comment at: include/support/itoa/itoa.h:123
+inline _LIBCPP_INLINE_VISIBILITY bool
+__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
+{

EricWF wrote:
> `__builtin_mul_overflow` works for `char` and `short`, so can't we just call 
> that?
I don't think so, it "works" after promotion.



Comment at: include/support/itoa/itoa.h:161
+template 
+struct _LIBCPP_HIDDEN traits : __traits<_Tp>
+{

EricWF wrote:
> `traits` needs to be a reserved name, and preferably a more descriptive one.
Similarly It's a standard name (std::string typedef), so user can't use a 
non-function style macro name to override it, IIUC.



Comment at: include/support/itoa/itoa.h:188
+
+template 
+static _LIBCPP_INLINE_VISIBILITY auto

EricWF wrote:
> What's wrong with using `std::inner_product`?
`__first != __last1` instead of `<`



Comment at: src/support/itoa/itoa.cpp:1
+// -*- C++ -*-
+//===--===//

EricWF wrote:
> This file should be renamed `charconv.cpp` and moved into the main source 
> directory.
We are going to have floating point cpp files so I don't think that one 
charconv.cpp is enough.



Comment at: src/support/itoa/itoa.cpp:35
+
+#define APPEND1(i)  \
+do  \

EricWF wrote:
> Any reason these can't be `static` functions? The compiler should optimize 
> them away nicely.
Although yes, but that's what the author provides.  It's an implementation 
file, so it doesn't matter I guess.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



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


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-02-09 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

@lichray I should have mentioned: Although this header is C++17 only, the bits 
compiled into the dylib need to compile as C++11 still.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41458



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


[PATCH] D41458: [libc++][C++17] Elementary string conversions for integral types

2018-02-09 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

Some initial thoughts.

@mclow.lists Are you planning on moving forward with your implementation as 
well?




Comment at: include/charconv:89
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum class _LIBCPP_ENUM_VIS chars_format

We need to hide these names when `_LIBCPP_STD_VER < 17`, since we're not 
allowed to introduce new names into namespace `std` in older dialects.



Comment at: include/charconv:90
+
+enum class _LIBCPP_ENUM_VIS chars_format
+{

enum types should have their underlying integer type explicitly specified. 
Otherwise their size and ABI can break when users specify `-short-enums`



Comment at: include/charconv:114
+template 
+inline _LIBCPP_INLINE_VISIBILITY auto
+__complement(_Tp __x) -> _Tp

No reason for using trailing return  type syntax here.



Comment at: include/charconv:122
+template 
+inline _LIBCPP_INLINE_VISIBILITY auto
+__to_unsigned(_Tp __x) -> typename make_unsigned<_Tp>::type

Same as above. There's no reason to deviate from the typical libc++ style and 
use trailing return types here.



Comment at: include/charconv:151
+
+#if __has_builtin(__builtin_clzll)
+if (__tx::digits <= __diff || __tx::width(__value) <= __diff)

`` already has a `__clz` wrapper for `__builtin_clz` et al. We 
should use that instead. That also allows us to get rid of the fallback 
implementation, and it correctly uses the builtin for compilers like GCC which 
don't provide `__has_builtin`.



Comment at: include/support/itoa/itoa.h:1
+// -*- C++ -*-
+//===- support/itoa/itoa.h 
===//

I would rather not introduce another header for this. I think it should go 
directly in the `charconv` header.



Comment at: include/support/itoa/itoa.h:24
+
+static constexpr uint64_t __pow10_64[] = {
+UINT64_C(0),

I'm not sure I love having static globals in the headers, but I can't think of 
a better way to write this.



Comment at: include/support/itoa/itoa.h:29
+UINT64_C(1000),
+UINT64_C(1),
+UINT64_C(10),

The `UINT64_C` and `UINT32_C` macros are non-standard, so I would rather not 
use them in a header.

Additionally, the compiler should correctly convert the integer type to the 
array's element type, no?



Comment at: include/support/itoa/itoa.h:47
+
+static constexpr uint32_t __pow10_32[] = {
+UINT32_C(0),  UINT32_C(10),   UINT32_C(100),

I suspect we can use `__pow10_64` in the 32 bit case as well to avoid emitting 
another static global.



Comment at: include/support/itoa/itoa.h:54
+
+#if __has_builtin(__builtin_clzll)
+

Use `__clz` from ``. You can assume we always have that.



Comment at: include/support/itoa/itoa.h:57
+inline _LIBCPP_INLINE_VISIBILITY auto
+__u64digits10(uint64_t __x) -> int
+{

`__u64digits10` and `__u32digits10` can be folded into `width`, since it's the 
only caller.



Comment at: include/support/itoa/itoa.h:72
+
+extern _LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
+extern _LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);

We don't marke functions in the dylib with extern.



Comment at: include/support/itoa/itoa.h:76
+template 
+struct _LIBCPP_HIDDEN __traits
+{

Maybe a more descriptive name than `__traits`?



Comment at: include/support/itoa/itoa.h:81
+#if __has_builtin(__builtin_clzll)
+static _LIBCPP_INLINE_VISIBILITY auto width(_Tp __v) -> int
+{

`width`, `convert` and `pow` need to be reserved names.



Comment at: include/support/itoa/itoa.h:123
+inline _LIBCPP_INLINE_VISIBILITY bool
+__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
+{

`__builtin_mul_overflow` works for `char` and `short`, so can't we just call 
that?



Comment at: include/support/itoa/itoa.h:144
+static_assert(is_unsigned<_Tp>::value, "");
+#if __has_builtin(__builtin_mul_overflow)
+return __builtin_mul_overflow(__a, __b, &__r);

GCC provides these builtins but `__has_builtin` won't detect them.

We can probably safely assume that every compiler except 
`_LIBCPP_COMPILER_MSVC` provides them, and only work around MSVC.



Comment at: include/support/itoa/itoa.h:161
+template 
+struct _LIBCPP_HIDDEN traits : __traits<_Tp>
+{

`traits` needs to be a reserved name, and preferably a more descriptive one.



Comment at: include/support/itoa/itoa.h:188
+
+template 
+static _LIBCPP_INLINE_VISIBILITY auto

What's wrong with using `std::inner_product`?



[PATCH] D43153: [clang] Implement P0692 "Access Checking on Specializations"

2018-02-09 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

How do you avoid suppressing diagnostics in the declaration of a template that 
is not a partial specialization? For example:

  class A { class B {}; };
  template A::B x; // error, but...
  template A::B x; // ok!

I would expect you'd need to delay the access checking diagnostics here until 
the declaration is complete and you find out whether you have a partial 
specialization or not.


Repository:
  rC Clang

https://reviews.llvm.org/D43153



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


[PATCH] D42779: [analyzer] NFC: Make sure we don't ever inline the constructor for which the temporary destructor is noreturn and missing.

2018-02-09 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL324802: [analyzer] NFC: Assert that our fix for noreturn 
destructors keeps working. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D42779?vs=133675=133737#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D42779

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp


Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -356,20 +356,30 @@
   // paths when no-return temporary destructors are used for assertions.
   const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
   if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
-  const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
-  if (Target && isa(Target) &&
-  Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
+if (Target && isa(Target) &&
+Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+
+  // If we've inlined the constructor, then DstEvaluated would be empty.
+  // In this case we still want a sink, which could be implemented
+  // in processCallExit. But we don't have that implemented at the moment,
+  // so if you hit this assertion, see if you can avoid inlining
+  // the respective constructor when analyzer-config cfg-temporary-dtors
+  // is set to false.
+  // Otherwise there's nothing wrong with inlining such constructor.
+  assert(!DstEvaluated.empty() &&
+ "We should not have inlined this constructor!");
 
   for (ExplodedNode *N : DstEvaluated) {
 Bldr.generateSink(CE, N, N->getState());
   }
 
-  // There is no need to run the PostCall and PostStmtchecker
+  // There is no need to run the PostCall and PostStmt checker
   // callbacks because we just generated sinks on all nodes in th
   // frontier.
   return;
 }
- }
+  }
 
   ExplodedNodeSet DstPostCall;
   getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,


Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -356,20 +356,30 @@
   // paths when no-return temporary destructors are used for assertions.
   const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
   if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
-  const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
-  if (Target && isa(Target) &&
-  Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
+if (Target && isa(Target) &&
+Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+
+  // If we've inlined the constructor, then DstEvaluated would be empty.
+  // In this case we still want a sink, which could be implemented
+  // in processCallExit. But we don't have that implemented at the moment,
+  // so if you hit this assertion, see if you can avoid inlining
+  // the respective constructor when analyzer-config cfg-temporary-dtors
+  // is set to false.
+  // Otherwise there's nothing wrong with inlining such constructor.
+  assert(!DstEvaluated.empty() &&
+ "We should not have inlined this constructor!");
 
   for (ExplodedNode *N : DstEvaluated) {
 Bldr.generateSink(CE, N, N->getState());
   }
 
-  // There is no need to run the PostCall and PostStmtchecker
+  // There is no need to run the PostCall and PostStmt checker
   // callbacks because we just generated sinks on all nodes in th
   // frontier.
   return;
 }
- }
+  }
 
   ExplodedNodeSet DstPostCall;
   getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r324802 - [analyzer] NFC: Assert that our fix for noreturn destructors keeps working.

2018-02-09 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Fri Feb  9 19:14:22 2018
New Revision: 324802

URL: http://llvm.org/viewvc/llvm-project?rev=324802=rev
Log:
[analyzer] NFC: Assert that our fix for noreturn destructors keeps working.

Massive false positives were known to be caused by continuing the analysis
after a destructor with a noreturn attribute has been executed in the program
but not modeled in the analyzer due to being missing in the CFG.

Now that work is being done on enabling the modeling of temporary constructors
and destructors in the CFG, we need to make sure that the heuristic that
suppresses these false positives keeps working when such modeling is disabled.
In particular, different code paths open up when the corresponding constructor
is being inlined during analysis.

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=324802=324801=324802=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Fri Feb  9 19:14:22 2018
@@ -356,20 +356,30 @@ void ExprEngine::VisitCXXConstructExpr(c
   // paths when no-return temporary destructors are used for assertions.
   const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
   if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
-  const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
-  if (Target && isa(Target) &&
-  Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
+if (Target && isa(Target) &&
+Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+
+  // If we've inlined the constructor, then DstEvaluated would be empty.
+  // In this case we still want a sink, which could be implemented
+  // in processCallExit. But we don't have that implemented at the moment,
+  // so if you hit this assertion, see if you can avoid inlining
+  // the respective constructor when analyzer-config cfg-temporary-dtors
+  // is set to false.
+  // Otherwise there's nothing wrong with inlining such constructor.
+  assert(!DstEvaluated.empty() &&
+ "We should not have inlined this constructor!");
 
   for (ExplodedNode *N : DstEvaluated) {
 Bldr.generateSink(CE, N, N->getState());
   }
 
-  // There is no need to run the PostCall and PostStmtchecker
+  // There is no need to run the PostCall and PostStmt checker
   // callbacks because we just generated sinks on all nodes in th
   // frontier.
   return;
 }
- }
+  }
 
   ExplodedNodeSet DstPostCall;
   getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,


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


[PATCH] D43153: [clang] Implement P0692 "Access Checking on Specializations"

2018-02-09 Thread Anton Bikineev via Phabricator via cfe-commits
AntonBikineev created this revision.
AntonBikineev added reviewers: rsmith, lebedev.ri.

This is an attempt to implement P0692 

Please note a couple of things:

1. given that clang already suppresses access checks on explicit 
specializations of classes as an extension, I decided to not make the feature 
C++17-specific and backport it to previous standards. Not sure that this is 
right though;
2. I'm also not sure that ParseOptionalCXXScopeSpecifer in a declarator is the 
correct place for suppressing checks.


Repository:
  rC Clang

https://reviews.llvm.org/D43153

Files:
  include/clang/Parse/RAIIObjectsForParser.h
  include/clang/Sema/DeclSpec.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/SemaCXX/access.cpp

Index: test/SemaCXX/access.cpp
===
--- test/SemaCXX/access.cpp
+++ test/SemaCXX/access.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
 
 class C {
 struct S; // expected-note {{previously declared 'private' here}}
@@ -169,3 +169,103 @@
   }
   void bar() { foo(); }
 }
+
+namespace P0692 {
+  namespace class_ {
+template 
+class trait_type {};
+   
+template 
+class trait_nontype;
+
+template  class>
+class trait_template;
+
+class A {
+  class B1 {}; // expected-note 2{{here}}
+
+  template 
+  class B2 {}; // expected-note 2{{here}}
+
+  class B3 {};
+   
+  static const int I = 0; // expected-note 4{{here}}
+};
+   
+template 
+class trait_type {
+  void use_private(int = A::I) { // expected-error {{private}}
+A::B2 error; // expected-error {{private}}
+  }
+};
+
+template  class T>
+class trait_type {
+  static const int I = A::I; // expected-error {{private}}
+};
+   
+template <>
+class trait_type
+  : A::B1 { // expected-error {{private}}
+  void use_private(int = A::I) { // expected-error {{private}}
+A::B1 error; // expected-error {{private}}
+  }
+};
+
+template class trait_type;
+
+template <>
+class trait_nontype {
+  static const int I = A::I; // expected-error {{private}}
+};
+
+template <>
+class trait_template {
+  A::B2 error; // expected-error {{private}}
+};
+  }
+
+  namespace function {
+class A {
+  class B1 {}; // expected-note 1{{here}}
+
+  class B2 {};
+   
+  using Int = int; // expected-note 1{{here}}
+};
+   
+template 
+void foo1() {}
+
+template <> void foo1() {
+A::B1 error; // expected-error {{private}}
+}
+
+template void foo1();
+
+template 
+void foo2(A::Int) {} // expected-error {{private}}
+  }
+
+  namespace variable {
+class A {
+  class B1 {};
+
+  template 
+  class B2 {};
+   
+  static const int I = 0; // expected-note 2{{here}}
+};
+
+template 
+int var = 0;
+
+template <>
+int var =
+A::I; // expected-error {{private}}
+
+template 
+int var =
+A::I; // expected-error {{private}}
+  }
+}
Index: test/CXX/drs/dr1xx.cpp
===
--- test/CXX/drs/dr1xx.cpp
+++ test/CXX/drs/dr1xx.cpp
@@ -917,12 +917,12 @@
   template  void C::g() {}
 
   class A {
-class B {}; // expected-note {{here}}
+class B {};
 void f();
   };
 
   template void C::f();
-  template <> void C::g(); // expected-error {{private}}
+  template <> void C::g();
 
   void A::f() {
 C cb;
Index: lib/Parse/ParseTemplate.cpp
===
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -235,7 +235,10 @@
 
   // Parse the declarator.
   ParsingDeclarator DeclaratorInfo(*this, DS, (DeclaratorContext)Context);
+  DeclaratorInfo.setTemplateDeclOrSpec(TemplateInfo.Kind !=
+   ParsedTemplateInfo::NonTemplate);
   ParseDeclarator(DeclaratorInfo);
+
   // Error parsing the declarator?
   if (!DeclaratorInfo.hasName()) {
 // If so, skip until the semi-colon or a }.
Index: lib/Parse/ParseDeclCXX.cpp
===
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -1375,15 +1375,22 @@
   //   The usual access checking rules do not apply to names used to specify
   //   explicit instantiations.
   //
-  // As an extension we do not perform access checking on the names used to
-  // specify explicit specializations either. This is important to allow
-  // specializing traits classes for private types.
+  // C++2a [temp.spec] 17.8/6:
+  //   The usual access checking rules do not apply to names in a declaration
+  //   of an explicit instantiation or explicit specialization, 

r324801 - [analyzer] Fix a merge error in -analyzer-config tests.

2018-02-09 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Fri Feb  9 19:04:59 2018
New Revision: 324801

URL: http://llvm.org/viewvc/llvm-project?rev=324801=rev
Log:
[analyzer] Fix a merge error in -analyzer-config tests.

It was introduced when two -analyzer-config options were added almost
simultaneously in r324793 and r324668 and the option count was not
rebased correctly in the tests.

Fixes the buildbots.

Modified:
cfe/trunk/test/Analysis/analyzer-config.c
cfe/trunk/test/Analysis/analyzer-config.cpp

Modified: cfe/trunk/test/Analysis/analyzer-config.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-config.c?rev=324801=324800=324801=diff
==
--- cfe/trunk/test/Analysis/analyzer-config.c (original)
+++ cfe/trunk/test/Analysis/analyzer-config.c Fri Feb  9 19:04:59 2018
@@ -34,4 +34,4 @@ void foo() {
 // CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 21
+// CHECK-NEXT: num-entries = 22

Modified: cfe/trunk/test/Analysis/analyzer-config.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-config.cpp?rev=324801=324800=324801=diff
==
--- cfe/trunk/test/Analysis/analyzer-config.cpp (original)
+++ cfe/trunk/test/Analysis/analyzer-config.cpp Fri Feb  9 19:04:59 2018
@@ -45,4 +45,4 @@ public:
 // CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 26
+// CHECK-NEXT: num-entries = 27


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


[PATCH] D42721: [analyzer] NFC: Use construction contexts for finding the target region for the construction.

2018-02-09 Thread Phabricator via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL324800: [analyzer] NFC: Use CFG construction contexts 
instead of homemade lookahead. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D42721?vs=133732=133735#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D42721

Files:
  cfe/trunk/include/clang/Analysis/CFG.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp

Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -114,12 +114,14 @@
   const LocationContext *LCtx = Pred->getLocationContext();
   ProgramStateRef State = Pred->getState();
 
-  // See if we're constructing an existing region by looking at the next
-  // element in the CFG.
-
-  if (auto Elem = findElementDirectlyInitializedByCurrentConstructor()) {
-if (Optional StmtElem = Elem->getAs()) {
-  if (const CXXNewExpr *CNE = dyn_cast(StmtElem->getStmt())) {
+  // See if we're constructing an existing region by looking at the
+  // current construction context.
+  const NodeBuilderContext  = getBuilderContext();
+  const CFGBlock *B = CurrBldrCtx.getBlock();
+  const CFGElement  = (*B)[currStmtIdx];
+  if (auto CC = E.getAs()) {
+if (const Stmt *TriggerStmt = CC->getTriggerStmt()) {
+  if (const CXXNewExpr *CNE = dyn_cast(TriggerStmt)) {
 if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
   // TODO: Detect when the allocator returns a null pointer.
   // Constructor shall not be called in this case.
@@ -135,7 +137,7 @@
 return MR;
   }
 }
-  } else if (auto *DS = dyn_cast(StmtElem->getStmt())) {
+  } else if (auto *DS = dyn_cast(TriggerStmt)) {
 if (const auto *Var = dyn_cast(DS->getSingleDecl())) {
   if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) {
 SVal LValue = State->getLValue(Var, LCtx);
@@ -145,11 +147,9 @@
 return LValue.getAsRegion();
   }
 }
-  } else {
-llvm_unreachable("Unexpected directly initialized element!");
   }
-} else if (Optional InitElem = Elem->getAs()) {
-  const CXXCtorInitializer *Init = InitElem->getInitializer();
+  // TODO: Consider other directly initialized elements.
+} else if (const CXXCtorInitializer *Init = CC->getTriggerInit()) {
   assert(Init->isAnyMemberInitializer());
   const CXXMethodDecl *CurCtor = cast(LCtx->getDecl());
   Loc ThisPtr =
@@ -183,53 +183,6 @@
   return MRMgr.getCXXTempObjectRegion(CE, LCtx);
 }
 
-/// Returns true if the initializer for \Elem can be a direct
-/// constructor.
-static bool canHaveDirectConstructor(CFGElement Elem){
-  // DeclStmts and CXXCtorInitializers for fields can be directly constructed.
-
-  if (Optional StmtElem = Elem.getAs()) {
-if (isa(StmtElem->getStmt())) {
-  return true;
-}
-if (isa(StmtElem->getStmt())) {
-  return true;
-}
-  }
-
-  if (Elem.getKind() == CFGElement::Initializer) {
-return true;
-  }
-
-  return false;
-}
-
-Optional
-ExprEngine::findElementDirectlyInitializedByCurrentConstructor() {
-  const NodeBuilderContext  = getBuilderContext();
-  // See if we're constructing an existing region by looking at the next
-  // element in the CFG.
-  const CFGBlock *B = CurrBldrCtx.getBlock();
-  assert(isa(((*B)[currStmtIdx]).castAs().getStmt()));
-  unsigned int NextStmtIdx = currStmtIdx + 1;
-  if (NextStmtIdx >= B->size())
-return None;
-
-  CFGElement Next = (*B)[NextStmtIdx];
-
-  // Is this a destructor? If so, we might be in the middle of an assignment
-  // to a local or member: look ahead one more element to see what we find.
-  while (Next.getAs() && NextStmtIdx + 1 < B->size()) {
-++NextStmtIdx;
-Next = (*B)[NextStmtIdx];
-  }
-
-  if (canHaveDirectConstructor(Next))
-return Next;
-
-  return None;
-}
-
 const CXXConstructExpr *
 ExprEngine::findDirectConstructorForCurrentCFGElement() {
   // Go backward in the CFG to see if the previous element (ignoring
@@ -241,7 +194,6 @@
 return nullptr;
 
   const CFGBlock *B = getBuilderContext().getBlock();
-  assert(canHaveDirectConstructor((*B)[currStmtIdx]));
 
   unsigned int PreviousStmtIdx = currStmtIdx - 1;
   CFGElement Previous = (*B)[PreviousStmtIdx];
Index: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -665,13 +665,6 @@
   /// constructing 

r324800 - [analyzer] NFC: Use CFG construction contexts instead of homemade lookahead.

2018-02-09 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Fri Feb  9 18:55:08 2018
New Revision: 324800

URL: http://llvm.org/viewvc/llvm-project?rev=324800=rev
Log:
[analyzer] NFC: Use CFG construction contexts instead of homemade lookahead.

The analyzer was relying on peeking the next CFG element during analysis
whenever it was trying to figure out what object is being constructed
by a given constructor. This information is now available in the current CFG
element in all cases that were previously supported by the analyzer,
so no complicated lookahead is necessary anymore.

No functional change intended - the context in the CFG should for now be
available if and only if it was previously discoverable via CFG lookahead.

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

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

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=324800=324799=324800=diff
==
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Fri Feb  9 18:55:08 2018
@@ -162,6 +162,8 @@ public:
 
   bool isNull() const { return Trigger.isNull(); }
 
+  TriggerTy getTrigger() const { return Trigger; }
+
   const Stmt *getTriggerStmt() const {
 return Trigger.dyn_cast();
   }
@@ -192,6 +194,14 @@ public:
 return static_cast(Data2.getPointer());
   }
 
+  QualType getType() const {
+return cast(getStmt())->getType();
+  }
+
+  ConstructionContext::TriggerTy getTrigger() const {
+return getConstructionContext()->getTrigger();
+  }
+
   const Stmt *getTriggerStmt() const {
 return getConstructionContext()->getTriggerStmt();
   }

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=324800=324799=324800=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Fri 
Feb  9 18:55:08 2018
@@ -665,13 +665,6 @@ private:
   /// constructing into an existing region.
   const CXXConstructExpr *findDirectConstructorForCurrentCFGElement();
 
-  /// For a CXXConstructExpr, walk forward in the current CFG block to find the
-  /// CFGElement for the DeclStmt or CXXInitCtorInitializer or CXXNewExpr which
-  /// is directly constructed by this constructor. Returns None if the current
-  /// constructor expression did not directly construct into an existing
-  /// region.
-  Optional findElementDirectlyInitializedByCurrentConstructor();
-
   /// 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

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=324800=324799=324800=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Fri Feb  9 18:55:08 2018
@@ -114,12 +114,14 @@ ExprEngine::getRegionForConstructedObjec
   const LocationContext *LCtx = Pred->getLocationContext();
   ProgramStateRef State = Pred->getState();
 
-  // See if we're constructing an existing region by looking at the next
-  // element in the CFG.
-
-  if (auto Elem = findElementDirectlyInitializedByCurrentConstructor()) {
-if (Optional StmtElem = Elem->getAs()) {
-  if (const CXXNewExpr *CNE = dyn_cast(StmtElem->getStmt())) {
+  // See if we're constructing an existing region by looking at the
+  // current construction context.
+  const NodeBuilderContext  = getBuilderContext();
+  const CFGBlock *B = CurrBldrCtx.getBlock();
+  const CFGElement  = (*B)[currStmtIdx];
+  if (auto CC = E.getAs()) {
+if (const Stmt *TriggerStmt = CC->getTriggerStmt()) {
+  if (const CXXNewExpr *CNE = dyn_cast(TriggerStmt)) {
 if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
   // TODO: Detect when the allocator returns a null pointer.
   // Constructor shall not be called in this case.
@@ -135,7 +137,7 @@ ExprEngine::getRegionForConstructedObjec
 return MR;
   }
 }
-  } else if (auto *DS = dyn_cast(StmtElem->getStmt())) {
+  } else if (auto *DS = dyn_cast(TriggerStmt)) {
 if (const auto *Var = dyn_cast(DS->getSingleDecl())) {
   if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) {
 

[PATCH] D42344: [libc++] Use multi-key tree search for {map, set}::{count, equal_range}

2018-02-09 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF closed this revision.
EricWF added a comment.

Committed as r324799.

Thank you!


https://reviews.llvm.org/D42344



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


[libcxx] r324799 - Use multi-key tree search for {map, set}::{count, equal_range}

2018-02-09 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Fri Feb  9 18:53:47 2018
New Revision: 324799

URL: http://llvm.org/viewvc/llvm-project?rev=324799=rev
Log:
Use multi-key tree search for {map, set}::{count, equal_range}

Patch from ngolovl...@gmail.com
Reviewed as: https://reviews.llvm.org/D42344

As described in llvm.org/PR30959, the current
implementation of std::{map, key}::{count, equal_range} in libcxx is
non-conforming. Quoting the C++14 standard [associative.reqmts]p3

> The phrase “equivalence of keys” means the equivalence relation imposed by
> the comparison and not the operator== on keys. That is, two keys k1 and k2 are
> considered to be equivalent if for the comparison object comp,
> comp(k1, k2) == false && comp(k2, k1) == false.

In the same section, the requirements table states the following:

> a.equal_range(k) equivalent to make_pair(a.lower_bound(k), a.upper_bound(k))
> a.count(k) returns the number of elements with key equivalent to k

The behaviour of libstdc++ seems to conform to the standard here.

Added:

libcxx/trunk/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp

libcxx/trunk/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp

libcxx/trunk/test/std/containers/associative/multimap/multimap.ops/count_transparent.pass.cpp

libcxx/trunk/test/std/containers/associative/multimap/multimap.ops/equal_range_transparent.pass.cpp

libcxx/trunk/test/std/containers/associative/multiset/count_transparent.pass.cpp

libcxx/trunk/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp
libcxx/trunk/test/std/containers/associative/set/count_transparent.pass.cpp

libcxx/trunk/test/std/containers/associative/set/equal_range_transparent.pass.cpp
Modified:
libcxx/trunk/include/map
libcxx/trunk/include/set

Modified: libcxx/trunk/include/map
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/map?rev=324799=324798=324799=diff
==
--- libcxx/trunk/include/map (original)
+++ libcxx/trunk/include/map Fri Feb  9 18:53:47 2018
@@ -1228,7 +1228,7 @@ public:
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
-count(const _K2& __k) const {return __tree_.__count_unique(__k);}
+count(const _K2& __k) const {return __tree_.__count_multi(__k);}
 #endif
 _LIBCPP_INLINE_VISIBILITY
 iterator lower_bound(const key_type& __k)
@@ -1275,11 +1275,11 @@ public:
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, 
_K2>::value,pair>::type
-equal_range(const _K2& __k)   {return 
__tree_.__equal_range_unique(__k);}
+equal_range(const _K2& __k)   {return 
__tree_.__equal_range_multi(__k);}
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, 
_K2>::value,pair>::type
-equal_range(const _K2& __k) const {return 
__tree_.__equal_range_unique(__k);}
+equal_range(const _K2& __k) const {return 
__tree_.__equal_range_multi(__k);}
 #endif
 
 private:

Modified: libcxx/trunk/include/set
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/set?rev=324799=324798=324799=diff
==
--- libcxx/trunk/include/set (original)
+++ libcxx/trunk/include/set Fri Feb  9 18:53:47 2018
@@ -668,7 +668,7 @@ public:
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
-count(const _K2& __k) const{return 
__tree_.__count_unique(__k);}
+count(const _K2& __k) const{return 
__tree_.__count_multi(__k);}
 #endif
 _LIBCPP_INLINE_VISIBILITY
 iterator lower_bound(const key_type& __k)
@@ -715,11 +715,11 @@ public:
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, 
_K2>::value,pair>::type
-equal_range(const _K2& __k)   {return 
__tree_.__equal_range_unique(__k);}
+equal_range(const _K2& __k)   {return 
__tree_.__equal_range_multi(__k);}
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, 
_K2>::value,pair>::type
-equal_range(const _K2& __k) const {return 
__tree_.__equal_range_unique(__k);}
+equal_range(const _K2& __k) const {return 
__tree_.__equal_range_multi(__k);}
 #endif
 };
 

Added: 
libcxx/trunk/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp?rev=324799=auto
==
--- 
libcxx/trunk/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp
 (added)

[PATCH] D42719: [CFG] [analyzer] Add construction context when constructor is wrapped into ExprWithCleanups.

2018-02-09 Thread Phabricator via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL324798: [CFG] Provide construction contexts when 
constructors have cleanups. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D42719?vs=133142=133733#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D42719

Files:
  cfe/trunk/lib/Analysis/CFG.cpp
  cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
  cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp

Index: cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
===
--- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
+++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
@@ -92,18 +92,45 @@
   C c{new C()};
 }
 
-// TODO: Should find construction target here.
 // CHECK: void simpleVariableInitializedByValue()
 // CHECK:  1: C::get
 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
 // CHECK-NEXT: 3: [B1.2]()
 // CHECK-NEXT: 4: [B1.3]
-// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, class C)
+// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C)
 // CHECK-NEXT: 6: C c = C::get();
 void simpleVariableInitializedByValue() {
   C c = C::get();
 }
 
+// TODO: Should find construction target for the three temporaries as well.
+// CHECK: void simpleVariableWithTernaryOperator(bool coin)
+// CHECK:[B1]
+// CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6]
+// CHECK-NEXT: 2: [B1.1]
+// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C)
+// CHECK-NEXT: 4: C c = coin ? C::get() : C(0);
+// CHECK:[B2]
+// CHECK-NEXT: 1: C::get
+// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
+// CHECK-NEXT: 3: [B2.2]()
+// CHECK-NEXT: 4: [B2.3]
+// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class C)
+// CHECK:[B3]
+// CHECK-NEXT: 1: 0
+// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
+// CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, class C)
+// CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
+// CHECK-NEXT: 5: [B3.4]
+// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, class C)
+// CHECK:[B4]
+// CHECK-NEXT: 1: coin
+// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK-NEXT: T: [B4.2] ? ... : ...
+void simpleVariableWithTernaryOperator(bool coin) {
+  C c = coin ? C::get() : C(0);
+}
+
 // TODO: Should find construction target here.
 // CHECK: void referenceVariableWithConstructor()
 // CHECK:  1: 0
@@ -125,6 +152,34 @@
   const C  = C();
 }
 
+// TODO: Should find construction targets here.
+// CHECK: void referenceVariableWithTernaryOperator(bool coin)
+// CHECK:[B1]
+// CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6]
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C)
+// CHECK-NEXT: 3: [B1.2]
+// CHECK-NEXT: 4: const C  = coin ? C::get() : C(0);
+// CHECK:[B2]
+// CHECK-NEXT: 1: C::get
+// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
+// CHECK-NEXT: 3: [B2.2]()
+// CHECK-NEXT: 4: [B2.3]
+// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class C)
+// CHECK:[B3]
+// CHECK-NEXT: 1: 0
+// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
+// CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, class C)
+// CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
+// CHECK-NEXT: 5: [B3.4]
+// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, class C)
+// CHECK:[B4]
+// CHECK-NEXT: 1: coin
+// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK-NEXT: T: [B4.2] ? ... : ...
+void referenceVariableWithTernaryOperator(bool coin) {
+  const C  = coin ? C::get() : C(0);
+}
+
 } // end namespace decl_stmt
 
 namespace ctor_initializers {
@@ -148,6 +203,24 @@
 // CHECK:  1:  (CXXConstructExpr, D() (Delegating initializer), class ctor_initializers::D)
 // CHECK-NEXT: 2: D([B1.1]) (Delegating initializer)
   D(int): D() {}
+
+// CHECK: D(double)
+// CHECK:  1: C::get
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
+// CHECK-NEXT: 3: [B1.2]()
+// CHECK-NEXT: 4: [B1.3]
+// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, C([B1.4]) (Base initializer), class C)
+// CHECK-NEXT: 6: C([B1.5]) (Base initializer)
+// CHECK-NEXT: 7: CFGNewAllocator(C *)
+// CHECK-NEXT: 8: C::get
+// CHECK-NEXT: 9: [B1.8] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
+// CHECK-NEXT:10: [B1.9]()
+// CHECK-NEXT:11: [B1.10]
+// CHECK-NEXT:12: [B1.11] (CXXConstructExpr, [B1.13], class C)
+// CHECK-NEXT:13: new C([B1.12])
+// 

[PATCH] D42721: [analyzer] NFC: Use construction contexts for finding the target region for the construction.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 133732.
NoQ added a comment.

Rebase.


https://reviews.llvm.org/D42721

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

Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -114,12 +114,14 @@
   const LocationContext *LCtx = Pred->getLocationContext();
   ProgramStateRef State = Pred->getState();
 
-  // See if we're constructing an existing region by looking at the next
-  // element in the CFG.
-
-  if (auto Elem = findElementDirectlyInitializedByCurrentConstructor()) {
-if (Optional StmtElem = Elem->getAs()) {
-  if (const CXXNewExpr *CNE = dyn_cast(StmtElem->getStmt())) {
+  // See if we're constructing an existing region by looking at the
+  // current construction context.
+  const NodeBuilderContext  = getBuilderContext();
+  const CFGBlock *B = CurrBldrCtx.getBlock();
+  const CFGElement  = (*B)[currStmtIdx];
+  if (auto CC = E.getAs()) {
+if (const Stmt *TriggerStmt = CC->getTriggerStmt()) {
+  if (const CXXNewExpr *CNE = dyn_cast(TriggerStmt)) {
 if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
   // TODO: Detect when the allocator returns a null pointer.
   // Constructor shall not be called in this case.
@@ -135,7 +137,7 @@
 return MR;
   }
 }
-  } else if (auto *DS = dyn_cast(StmtElem->getStmt())) {
+  } else if (auto *DS = dyn_cast(TriggerStmt)) {
 if (const auto *Var = dyn_cast(DS->getSingleDecl())) {
   if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) {
 SVal LValue = State->getLValue(Var, LCtx);
@@ -145,11 +147,9 @@
 return LValue.getAsRegion();
   }
 }
-  } else {
-llvm_unreachable("Unexpected directly initialized element!");
   }
-} else if (Optional InitElem = Elem->getAs()) {
-  const CXXCtorInitializer *Init = InitElem->getInitializer();
+  // TODO: Consider other directly initialized elements.
+} else if (const CXXCtorInitializer *Init = CC->getTriggerInit()) {
   assert(Init->isAnyMemberInitializer());
   const CXXMethodDecl *CurCtor = cast(LCtx->getDecl());
   Loc ThisPtr =
@@ -183,53 +183,6 @@
   return MRMgr.getCXXTempObjectRegion(CE, LCtx);
 }
 
-/// Returns true if the initializer for \Elem can be a direct
-/// constructor.
-static bool canHaveDirectConstructor(CFGElement Elem){
-  // DeclStmts and CXXCtorInitializers for fields can be directly constructed.
-
-  if (Optional StmtElem = Elem.getAs()) {
-if (isa(StmtElem->getStmt())) {
-  return true;
-}
-if (isa(StmtElem->getStmt())) {
-  return true;
-}
-  }
-
-  if (Elem.getKind() == CFGElement::Initializer) {
-return true;
-  }
-
-  return false;
-}
-
-Optional
-ExprEngine::findElementDirectlyInitializedByCurrentConstructor() {
-  const NodeBuilderContext  = getBuilderContext();
-  // See if we're constructing an existing region by looking at the next
-  // element in the CFG.
-  const CFGBlock *B = CurrBldrCtx.getBlock();
-  assert(isa(((*B)[currStmtIdx]).castAs().getStmt()));
-  unsigned int NextStmtIdx = currStmtIdx + 1;
-  if (NextStmtIdx >= B->size())
-return None;
-
-  CFGElement Next = (*B)[NextStmtIdx];
-
-  // Is this a destructor? If so, we might be in the middle of an assignment
-  // to a local or member: look ahead one more element to see what we find.
-  while (Next.getAs() && NextStmtIdx + 1 < B->size()) {
-++NextStmtIdx;
-Next = (*B)[NextStmtIdx];
-  }
-
-  if (canHaveDirectConstructor(Next))
-return Next;
-
-  return None;
-}
-
 const CXXConstructExpr *
 ExprEngine::findDirectConstructorForCurrentCFGElement() {
   // Go backward in the CFG to see if the previous element (ignoring
@@ -241,7 +194,6 @@
 return nullptr;
 
   const CFGBlock *B = getBuilderContext().getBlock();
-  assert(canHaveDirectConstructor((*B)[currStmtIdx]));
 
   unsigned int PreviousStmtIdx = currStmtIdx - 1;
   CFGElement Previous = (*B)[PreviousStmtIdx];
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -665,13 +665,6 @@
   /// constructing into an existing region.
   const CXXConstructExpr *findDirectConstructorForCurrentCFGElement();
 
-  /// For a CXXConstructExpr, walk forward in the current CFG block to find the
-  /// CFGElement for the DeclStmt or CXXInitCtorInitializer or CXXNewExpr which
-  /// is directly constructed by this constructor. Returns None if the current
-  /// constructor expression did not directly construct into an existing
-  /// region.
-  Optional 

r324798 - [CFG] Provide construction contexts when constructors have cleanups.

2018-02-09 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Fri Feb  9 18:46:14 2018
New Revision: 324798

URL: http://llvm.org/viewvc/llvm-project?rev=324798=rev
Log:
[CFG] Provide construction contexts when constructors have cleanups.

Now that we make it possible to query the CFG constructor element to find
information about the construction site, possible cleanup work represented by
ExprWithCleanups should not prevent us from providing this information.

This allows us to have a correct construction context for variables initialized
"by value" via elidable copy-constructors, such as 'i' in

  iterator i = vector.begin();

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

Modified:
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=324798=324797=324798=diff
==
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Fri Feb  9 18:46:14 2018
@@ -1158,6 +1158,8 @@ void CFGBuilder::EnterConstructionContex
 assert(CurrentConstructionContext.isNull() &&
"Already within a construction context!");
 CurrentConstructionContext = ConstructionContext(Trigger);
+  } else if (auto *Cleanups = dyn_cast(Child)) {
+EnterConstructionContextIfNecessary(Trigger, Cleanups->getSubExpr());
   }
 }
 

Modified: cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cfg-rich-constructors.cpp?rev=324798=324797=324798=diff
==
--- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp (original)
+++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp Fri Feb  9 18:46:14 2018
@@ -92,18 +92,45 @@ void simpleVariableWithOperatorNewInBrac
   C c{new C()};
 }
 
-// TODO: Should find construction target here.
 // CHECK: void simpleVariableInitializedByValue()
 // CHECK:  1: C::get
 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class 
C (*)(void))
 // CHECK-NEXT: 3: [B1.2]()
 // CHECK-NEXT: 4: [B1.3]
-// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, class C)
+// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C)
 // CHECK-NEXT: 6: C c = C::get();
 void simpleVariableInitializedByValue() {
   C c = C::get();
 }
 
+// TODO: Should find construction target for the three temporaries as well.
+// CHECK: void simpleVariableWithTernaryOperator(bool coin)
+// CHECK:[B1]
+// CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6]
+// CHECK-NEXT: 2: [B1.1]
+// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C)
+// CHECK-NEXT: 4: C c = coin ? C::get() : C(0);
+// CHECK:[B2]
+// CHECK-NEXT: 1: C::get
+// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class 
C (*)(void))
+// CHECK-NEXT: 3: [B2.2]()
+// CHECK-NEXT: 4: [B2.3]
+// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class C)
+// CHECK:[B3]
+// CHECK-NEXT: 1: 0
+// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
+// CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, class C)
+// CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, 
class C)
+// CHECK-NEXT: 5: [B3.4]
+// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, class C)
+// CHECK:[B4]
+// CHECK-NEXT: 1: coin
+// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK-NEXT: T: [B4.2] ? ... : ...
+void simpleVariableWithTernaryOperator(bool coin) {
+  C c = coin ? C::get() : C(0);
+}
+
 // TODO: Should find construction target here.
 // CHECK: void referenceVariableWithConstructor()
 // CHECK:  1: 0
@@ -125,6 +152,34 @@ void referenceVariableWithInitializer()
   const C  = C();
 }
 
+// TODO: Should find construction targets here.
+// CHECK: void referenceVariableWithTernaryOperator(bool coin)
+// CHECK:[B1]
+// CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6]
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C)
+// CHECK-NEXT: 3: [B1.2]
+// CHECK-NEXT: 4: const C  = coin ? C::get() : C(0);
+// CHECK:[B2]
+// CHECK-NEXT: 1: C::get
+// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class 
C (*)(void))
+// CHECK-NEXT: 3: [B2.2]()
+// CHECK-NEXT: 4: [B2.3]
+// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class C)
+// CHECK:[B3]
+// CHECK-NEXT: 1: 0
+// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
+// CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, class C)
+// CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, 
class C)
+// CHECK-NEXT: 5: [B3.4]
+// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, class C)
+// CHECK:[B4]
+// CHECK-NEXT: 1: coin
+// CHECK-NEXT: 

r324796 - [CFG] Add construction context for constructor initializers.

2018-02-09 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Fri Feb  9 18:18:04 2018
New Revision: 324796

URL: http://llvm.org/viewvc/llvm-project?rev=324796=rev
Log:
[CFG] Add construction context for constructor initializers.

CFG elements for constructors of fields and base classes that are being
initialized before the body of the whole-class constructor starts can now be
queried to discover that they're indeed participating in initialization of their
respective fields or bases before the whole-class constructor kicks in.

CFG construction contexts are now capable of representing CXXCtorInitializer
triggers, which aren't considered to be statements in the Clang AST.

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

Modified:
cfe/trunk/include/clang/Analysis/CFG.h
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
cfe/trunk/test/Analysis/initializers-cfg-output.cpp

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=324796=324795=324796=diff
==
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Fri Feb  9 18:18:04 2018
@@ -145,19 +145,30 @@ protected:
 // necessary to express what memory is being initialized by
 // the construction.
 class ConstructionContext {
+public:
+  typedef llvm::PointerUnion TriggerTy;
+
+private:
   // The construction site - the statement that triggered the construction
   // for one of its parts. For instance, stack variable declaration statement
   // triggers construction of itself or its elements if it's an array,
   // new-expression triggers construction of the newly allocated object(s).
-  Stmt *Trigger = nullptr;
+  TriggerTy Trigger;
 
 public:
   ConstructionContext() = default;
-  ConstructionContext(Stmt *Trigger) : Trigger(Trigger) {}
+  ConstructionContext(TriggerTy Trigger)
+  : Trigger(Trigger) {}
 
-  bool isNull() const { return Trigger == nullptr; }
+  bool isNull() const { return Trigger.isNull(); }
 
-  const Stmt *getTriggerStmt() const { return Trigger; }
+  const Stmt *getTriggerStmt() const {
+return Trigger.dyn_cast();
+  }
+
+  const CXXCtorInitializer *getTriggerInit() const {
+return Trigger.dyn_cast();
+  }
 
   const ConstructionContext *getPersistentCopy(BumpVectorContext ) const {
 ConstructionContext *CC = C.getAllocator().Allocate();
@@ -185,6 +196,10 @@ public:
 return getConstructionContext()->getTriggerStmt();
   }
 
+  const CXXCtorInitializer *getTriggerInit() const {
+return getConstructionContext()->getTriggerInit();
+  }
+
 private:
   friend class CFGElement;
 

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=324796=324795=324796=diff
==
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Fri Feb  9 18:18:04 2018
@@ -654,7 +654,8 @@ private:
   // to the trigger statement. The construction context will be unset once
   // it is consumed when the CFG building procedure processes the
   // construct-expression and adds the respective CFGConstructor element.
-  void EnterConstructionContextIfNecessary(Stmt *Trigger, Stmt *Child);
+  void EnterConstructionContextIfNecessary(
+  ConstructionContext::TriggerTy Trigger, Stmt *Child);
   // Unset the construction context after consuming it. This is done 
immediately
   // after adding the CFGConstructor element, so there's no need to
   // do this manually in every Visit... function.
@@ -1147,8 +1148,8 @@ static const VariableArrayType *FindVA(c
   return nullptr;
 }
 
-void CFGBuilder::EnterConstructionContextIfNecessary(Stmt *Trigger,
- Stmt *Child) {
+void CFGBuilder::EnterConstructionContextIfNecessary(
+ConstructionContext::TriggerTy Trigger, Stmt *Child) {
   if (!BuildOpts.AddRichCXXConstructors)
 return;
   if (!Child)
@@ -1294,6 +1295,8 @@ CFGBlock *CFGBuilder::addInitializer(CXX
   appendInitializer(Block, I);
 
   if (Init) {
+EnterConstructionContextIfNecessary(I, Init);
+
 if (HasTemporaries) {
   // For expression with temporaries go directly to subexpression to omit
   // generating destructors for the second time.
@@ -4605,6 +4608,27 @@ public:
 
 } // namespace
 
+static void print_initializer(raw_ostream , StmtPrinterHelper ,
+  const CXXCtorInitializer *I) {
+  if (I->isBaseInitializer())
+OS << I->getBaseClass()->getAsCXXRecordDecl()->getName();
+  else if (I->isDelegatingInitializer())
+OS << I->getTypeSourceInfo()->getType()->getAsCXXRecordDecl()->getName();
+  else
+OS << I->getAnyMember()->getName();
+  OS << "(";
+  if (Expr *IE = I->getInit())
+IE->printPretty(OS, , PrintingPolicy(Helper.getLangOpts()));
+  OS << ")";
+
+  if 

[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-02-09 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: test/std/experimental/filesystem/lit.local.cfg:5
+
+# filesystem_test_helper uses random_device to generate random path.
+if 'libcpp-has-no-random-device' in config.available_features:

EricWF wrote:
> EricWF wrote:
> > I would rather keep these tests running using a different source for the 
> > random seed if possible.
> Perhaps the random generator could be initialized using 
> `std::chrono::system_clock::now().time_since_epoch().count()`, which should 
> produce more distinct values that the typical `time(NULL)` method used to 
> initialize `srand`.
Actually `std::chrono::high_resolution_clock` would be better.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



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


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-02-09 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: test/std/experimental/filesystem/lit.local.cfg:5
+
+# filesystem_test_helper uses random_device to generate random path.
+if 'libcpp-has-no-random-device' in config.available_features:

EricWF wrote:
> I would rather keep these tests running using a different source for the 
> random seed if possible.
Perhaps the random generator could be initialized using 
`std::chrono::system_clock::now().time_since_epoch().count()`, which should 
produce more distinct values that the typical `time(NULL)` method used to 
initialize `srand`.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



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


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-02-09 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

I think the direction here is OK. Although I really hate allowing bits of 
libc++ to be "optional". In this case it should be OK, but often it makes the 
library trickier to maintain -- and these configurations often go untested 
between releases.




Comment at: CMakeLists.txt:74
 option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
+option(LIBCXX_ENABLE_RANDOM_DEVICE "Build random_device class" On)
 

nit: `ON`



Comment at: test/std/experimental/filesystem/lit.local.cfg:5
+
+# filesystem_test_helper uses random_device to generate random path.
+if 'libcpp-has-no-random-device' in config.available_features:

I would rather keep these tests running using a different source for the random 
seed if possible.



Comment at: test/std/numerics/rand/rand.device/lit.local.cfg:1
+# Disable all of the random device tests if the correct feature is not 
available.
+if 'libcpp-has-no-random-device' in config.available_features:

There are only 3 tests under this directory. I would rather mark each one 
explicitly with `// UNSUPPORTED: libcpp-has-no-random-device`


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



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


r324794 - [CFG] Add construction context for simple variable declarations.

2018-02-09 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Fri Feb  9 17:55:23 2018
New Revision: 324794

URL: http://llvm.org/viewvc/llvm-project?rev=324794=rev
Log:
[CFG] Add construction context for simple variable declarations.

Constructors of simple variables now can be queried to discover that they're
constructing into simple variables.

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

Modified:
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp
cfe/trunk/test/Analysis/blocks.mm
cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
cfe/trunk/test/Analysis/cfg.cpp
cfe/trunk/test/Analysis/initializers-cfg-output.cpp
cfe/trunk/test/Analysis/lifetime-cfg-output.cpp

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=324794=324793=324794=diff
==
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Fri Feb  9 17:55:23 2018
@@ -2377,7 +2377,9 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(D
 
   autoCreateBlock();
   appendStmt(Block, DS);
-  
+
+  EnterConstructionContextIfNecessary(DS, Init);
+
   // Keep track of the last non-null block, as 'Block' can be nulled out
   // if the initializer expression is something like a 'while' in a
   // statement-expression.

Modified: cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp?rev=324794=324793=324794=diff
==
--- cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp (original)
+++ cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp Fri Feb  9 17:55:23 
2018
@@ -1,5 +1,16 @@
-// RUN: %clang_analyze_cc1 -fcxx-exceptions -fexceptions 
-analyzer-checker=debug.DumpCFG %s > %t 2>&1
-// RUN: FileCheck --input-file=%t %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -fexceptions 
-analyzer-checker=debug.DumpCFG -analyzer-config cfg-rich-constructors=false %s 
> %t 2>&1
+// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,WARNINGS %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -fexceptions 
-analyzer-checker=debug.DumpCFG -analyzer-config cfg-rich-constructors=true %s 
> %t 2>&1
+// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,ANALYZER %s
+
+// This file tests how we construct two different flavors of the Clang CFG -
+// the CFG used by the Sema analysis-based warnings and the CFG used by the
+// static analyzer. The difference in the behavior is checked via FileCheck
+// prefixes (WARNINGS and ANALYZER respectively). When introducing new analyzer
+// flags, no new run lines should be added - just these flags would go to the
+// respective line depending on where is it turned on and where is it turned
+// off. Feel free to add tests that test only one of the CFG flavors if you're
+// not sure how the other flavor is supposed to work in your case.
 
 class A {
 public:
@@ -32,7 +43,8 @@ extern const bool UV;
 // CHECK:  [B2 (ENTRY)]
 // CHECK-NEXT:   Succs (1): B1
 // CHECK:  [B1]
-// CHECK-NEXT:   1:  (CXXConstructExpr, class A)
+// WARNINGS-NEXT:   1:  (CXXConstructExpr, class A)
+// ANALYZER-NEXT:   1:  (CXXConstructExpr, [B1.2], class A)
 // CHECK-NEXT:   2: A a;
 // CHECK-NEXT:   3: a
 // CHECK-NEXT:   4: [B1.3] (ImplicitCastExpr, NoOp, const class A)
@@ -57,9 +69,11 @@ void test_const_ref() {
 // CHECK:  [B2 (ENTRY)]
 // CHECK-NEXT:   Succs (1): B1
 // CHECK:  [B1]
-// CHECK-NEXT:   1:  (CXXConstructExpr, class A [2])
+// WARNINGS-NEXT:   1:  (CXXConstructExpr, class A [2])
+// ANALYZER-NEXT:   1:  (CXXConstructExpr, [B1.2], class A [2])
 // CHECK-NEXT:   2: A a[2];
-// CHECK-NEXT:   3:  (CXXConstructExpr, class A [0])
+// WARNINGS-NEXT:   3:  (CXXConstructExpr, class A [0])
+// ANALYZER-NEXT:   3:  (CXXConstructExpr, [B1.4], class A [0])
 // CHECK-NEXT:   4: A b[0];
 // CHECK-NEXT:   5: [B1.2].~A() (Implicit destructor)
 // CHECK-NEXT:   Preds (1): B2
@@ -74,15 +88,19 @@ void test_array() {
 // CHECK:  [B2 (ENTRY)]
 // CHECK-NEXT:   Succs (1): B1
 // CHECK:  [B1]
-// CHECK-NEXT:   1:  (CXXConstructExpr, class A)
+// WARNINGS-NEXT:   1:  (CXXConstructExpr, class A)
+// ANALYZER-NEXT:   1:  (CXXConstructExpr, [B1.2], class A)
 // CHECK-NEXT:   2: A a;
-// CHECK-NEXT:   3:  (CXXConstructExpr, class A)
+// WARNINGS-NEXT:   3:  (CXXConstructExpr, class A)
+// ANALYZER-NEXT:   3:  (CXXConstructExpr, [B1.4], class A)
 // CHECK-NEXT:   4: A c;
-// CHECK-NEXT:   5:  (CXXConstructExpr, class A)
+// WARNINGS-NEXT:   5:  (CXXConstructExpr, class A)
+// ANALYZER-NEXT:   5:  (CXXConstructExpr, [B1.6], class A)
 // CHECK-NEXT:   6: A d;
 // CHECK-NEXT:   7: [B1.6].~A() (Implicit destructor)
 // CHECK-NEXT:   8: [B1.4].~A() (Implicit destructor)
-// CHECK-NEXT:   9:  (CXXConstructExpr, class A)
+// WARNINGS-NEXT:   9:  (CXXConstructExpr, class A)
+// ANALYZER-NEXT:   9:  

[PATCH] D43110: [Sema] Don't mark plain MS enums as fixed

2018-02-09 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.

Thanks! I'd noticed this weirdness but wasn't sure what we could do about it 
without breaking MS compat. I like this approach a lot.

If we want to change the C behavior too, I think that should be a separate 
change. How does MSVC behave in C mode?


https://reviews.llvm.org/D43110



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


[PATCH] D43131: [analyzer] Serialize statistics to plist when serialize-stats=true is set

2018-02-09 Thread George Karpenkov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC324793: [analyzer] Serialize statistics to plist when 
serialize-stats=true is set (authored by george.karpenkov, committed by ).
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43131?vs=133722=133727#toc

Repository:
  rC Clang

https://reviews.llvm.org/D43131

Files:
  include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
  lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
  lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
  lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
  test/Analysis/analyzer-config.c
  test/Analysis/analyzer-config.cpp
  test/Analysis/plist-stats-output.c

Index: include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
===
--- include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -277,6 +277,8 @@
   /// \sa StableReportFilename
   Optional StableReportFilename;
 
+  Optional SerializeStats;
+
   /// \sa getGraphTrimInterval
   Optional GraphTrimInterval;
 
@@ -538,6 +540,14 @@
   /// which accepts the values "true" and "false". Default = false
   bool shouldWriteStableReportFilename();
 
+  /// \return Whether the analyzer should
+  /// serialize statistics to plist output.
+  /// Statistics would be serialized in JSON format inside the main dictionary
+  /// under the \c statistics key.
+  /// Available only if compiled in assert mode or with LLVM statistics
+  /// explicitly enabled.
+  bool shouldSerializeStats();
+
   /// Returns whether irrelevant parts of a bug report path should be pruned
   /// out of the final output.
   ///
Index: test/Analysis/analyzer-config.cpp
===
--- test/Analysis/analyzer-config.cpp
+++ test/Analysis/analyzer-config.cpp
@@ -41,6 +41,7 @@
 // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
 // CHECK-NEXT: mode = deep
 // CHECK-NEXT: region-store-small-struct-limit = 2
+// CHECK-NEXT: serialize-stats = false
 // CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
Index: test/Analysis/plist-stats-output.c
===
--- test/Analysis/plist-stats-output.c
+++ test/Analysis/plist-stats-output.c
@@ -0,0 +1,14 @@
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core -analyzer-output=plist -analyzer-config serialize-stats=true -o %t.plist
+// REQUIRES: asserts
+// RUN: FileCheck --input-file=%t.plist %s
+
+int foo() {}
+
+
+// CHECK:  diagnostics
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT: statistics
+// CHECK-NEXT: {
+// CHECK: }
+// CHECK-NEXT: 
Index: test/Analysis/analyzer-config.c
===
--- test/Analysis/analyzer-config.c
+++ test/Analysis/analyzer-config.c
@@ -30,6 +30,7 @@
 // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
 // CHECK-NEXT: mode = deep
 // CHECK-NEXT: region-store-small-struct-limit = 2
+// CHECK-NEXT: serialize-stats = false
 // CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
===
--- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -188,7 +188,8 @@
   std::unique_ptr Mgr;
 
   /// Time the analyzes time of each translation unit.
-  static llvm::Timer* TUTotalTimer;
+  std::unique_ptr AnalyzerTimers;
+  std::unique_ptr TUTotalTimer;
 
   /// The information about analyzed functions shared throughout the
   /// translation unit.
@@ -201,15 +202,17 @@
 OutDir(outdir), Opts(std::move(opts)), Plugins(plugins),
 Injector(injector) {
 DigestAnalyzerOptions();
-if (Opts->PrintStats) {
-  llvm::EnableStatistics(false);
-  TUTotalTimer = new llvm::Timer("time", "Analyzer Total Time");
+if (Opts->PrintStats || Opts->shouldSerializeStats()) {
+  AnalyzerTimers = llvm::make_unique(
+  "analyzer", "Analyzer timers");
+  TUTotalTimer = llvm::make_unique(
+  "time", "Analyzer total time", *AnalyzerTimers);
+  llvm::EnableStatistics(/* PrintOnExit= */ false);
 }
   }
 
   ~AnalysisConsumer() override {
 if (Opts->PrintStats) {
-  delete TUTotalTimer;
   llvm::PrintStatistics();
 }
   }
@@ -394,8 +397,6 @@
 //===--===//
 // AnalysisConsumer implementation.
 //===--===//
-llvm::Timer* AnalysisConsumer::TUTotalTimer = nullptr;
-
 bool AnalysisConsumer::HandleTopLevelDecl(DeclGroupRef DG) {
   storeTopLevelDecls(DG);
   return true;
@@ -557,12 +558,6 @@
 RecVisitorBR = nullptr;
   }
 
-  // Explicitly destroy the PathDiagnosticConsumer.  

r324793 - [analyzer] Serialize statistics to plist when serialize-stats=true is set

2018-02-09 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Feb  9 17:49:20 2018
New Revision: 324793

URL: http://llvm.org/viewvc/llvm-project?rev=324793=rev
Log:
[analyzer] Serialize statistics to plist when serialize-stats=true is set

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

Added:
cfe/trunk/test/Analysis/plist-stats-output.c
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
cfe/trunk/test/Analysis/analyzer-config.c
cfe/trunk/test/Analysis/analyzer-config.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=324793=324792=324793=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Fri Feb  9 
17:49:20 2018
@@ -277,6 +277,8 @@ private:
   /// \sa StableReportFilename
   Optional StableReportFilename;
 
+  Optional SerializeStats;
+
   /// \sa getGraphTrimInterval
   Optional GraphTrimInterval;
 
@@ -538,6 +540,14 @@ public:
   /// which accepts the values "true" and "false". Default = false
   bool shouldWriteStableReportFilename();
 
+  /// \return Whether the analyzer should
+  /// serialize statistics to plist output.
+  /// Statistics would be serialized in JSON format inside the main dictionary
+  /// under the \c statistics key.
+  /// Available only if compiled in assert mode or with LLVM statistics
+  /// explicitly enabled.
+  bool shouldSerializeStats();
+
   /// Returns whether irrelevant parts of a bug report path should be pruned
   /// out of the final output.
   ///

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=324793=324792=324793=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Fri Feb  9 17:49:20 
2018
@@ -287,6 +287,12 @@ bool AnalyzerOptions::shouldWriteStableR
   /* Default = */ false);
 }
 
+bool AnalyzerOptions::shouldSerializeStats() {
+  return getBooleanOption(SerializeStats,
+  "serialize-stats",
+  /* Default = */ false);
+}
+
 int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal,
 const CheckerBase *C,
 bool SearchInParents) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=324793=324792=324793=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Fri Feb  9 17:49:20 
2018
@@ -16,9 +16,12 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Core/HTMLRewrite.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/IssueHash.h"
 #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
 using namespace clang;
@@ -30,6 +33,7 @@ namespace {
 const std::string OutputFile;
 const LangOptions 
 const bool SupportsCrossFileDiagnostics;
+const bool SerializeStatistics;
   public:
 PlistDiagnostics(AnalyzerOptions ,
  const std::string& prefix,
@@ -61,7 +65,8 @@ PlistDiagnostics::PlistDiagnostics(Analy
bool supportsMultipleFiles)
   : OutputFile(output),
 LangOpts(LO),
-SupportsCrossFileDiagnostics(supportsMultipleFiles) {}
+SupportsCrossFileDiagnostics(supportsMultipleFiles),
+SerializeStatistics(AnalyzerOpts.shouldSerializeStats()) {}
 
 void ento::createPlistDiagnosticConsumer(AnalyzerOptions ,
  PathDiagnosticConsumers ,
@@ -484,6 +489,15 @@ void PlistDiagnostics::FlushDiagnosticsI
 
   o << " \n";
 
+  if (llvm::AreStatisticsEnabled() && SerializeStatistics) {
+o << " statistics\n";
+std::string stats;
+llvm::raw_string_ostream os(stats);
+llvm::PrintStatisticsJSON(os);
+os.flush();
+EmitString(o, html::EscapeText(stats)) << '\n';
+  }
+
   // Finish.
   o << "\n";
 }

Modified: 

[PATCH] D42921: [CUDA] Add option to generate relocatable device code

2018-02-09 Thread Artem Belevich via Phabricator via cfe-commits
tra accepted this revision.
tra added inline comments.
This revision is now accepted and ready to land.



Comment at: include/clang/Driver/Options.td:572
+  HelpText<"Generate relocatable device code, also known as separate 
compilation mode.">;
+def fno_cuda_rdc : Flag<["-"], "fno-cuda-rdc">;
 def dA : Flag<["-"], "dA">, Group;

Does the options show up in clang --help? 
If it does, and if you plan to commit patches one at a time, we may want to 
make it hidden until everything is in place.


Repository:
  rC Clang

https://reviews.llvm.org/D42921



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


[PATCH] D42920: [CUDA] Fix test cuda-external-tools.cu

2018-02-09 Thread Artem Belevich via Phabricator via cfe-commits
tra accepted this revision.
tra added inline comments.
This revision is now accepted and ready to land.



Comment at: test/Driver/cuda-external-tools.cu:11
+// RUN: | FileCheck -check-prefix CHECK -check-prefix ARCH64 \
+// RUN: -check-prefix SM20 -check-prefix OPT0 %s
 // RUN: %clang -### -target x86_64-linux-gnu -O1 -c %s 2>&1 \

Nit: I'd use --check-prefixes=CHECK,ARCH64,SM20,OPT0 . Up to you.


Repository:
  rC Clang

https://reviews.llvm.org/D42920



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


[PATCH] D42310: Formalize FreeBSD support of compiler rt

2018-02-09 Thread Tom Rix via Phabricator via cfe-commits
trixirt added a comment.

The symlinks were useful in the transition from gcc to clang.
Now they don't serve any purpose.
Clang uses libcompiler_rt, not libgcc.


Repository:
  rC Clang

https://reviews.llvm.org/D42310



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


[PATCH] D41102: Setup clang-doc frontend framework

2018-02-09 Thread Julie Hockett via Phabricator via cfe-commits
juliehockett updated this revision to Diff 133726.
juliehockett added a comment.

Updating documentation


https://reviews.llvm.org/D41102

Files:
  CMakeLists.txt
  clang-doc/CMakeLists.txt
  clang-doc/ClangDoc.cpp
  clang-doc/ClangDoc.h
  clang-doc/ClangDocBinary.cpp
  clang-doc/ClangDocBinary.h
  clang-doc/ClangDocMapper.cpp
  clang-doc/ClangDocMapper.h
  clang-doc/ClangDocRepresentation.h
  clang-doc/tool/CMakeLists.txt
  clang-doc/tool/ClangDocMain.cpp
  docs/clang-doc.rst
  test/CMakeLists.txt
  test/clang-doc/mapper-namespace.cpp
  test/clang-doc/mapper-type.cpp

Index: test/clang-doc/mapper-type.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-type.cpp
@@ -0,0 +1,137 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc  --dump --omit-filenames -doxygen -p %t %t/test.cpp | FileCheck %s
+
+union A { int X; int Y; };
+// CHECK: ---
+// CHECK: KEY: A
+// CHECK: FullyQualifiedName: A
+// CHECK: Name: A
+// CHECK: TagType: 2
+// CHECK: ID: Member
+// CHECK: Type: int
+// CHECK: Name: A::X
+// CHECK: Access: 3
+// CHECK: ID: Member
+// CHECK: Type: int
+// CHECK: Name: A::Y
+// CHECK: Access: 3
+// CHECK: ---
+// CHECK: KEY: A::A
+// CHECK: FullyQualifiedName: A::A
+// CHECK: Name: A
+// CHECK: Namespace: A
+
+enum B { X, Y };
+// CHECK: ---
+// CHECK: KEY: B
+// CHECK: FullyQualifiedName: B
+// CHECK: Name: B
+// CHECK: ID: Member
+// CHECK: Type: X
+// CHECK: Access: 3
+// CHECK: ID: Member
+// CHECK: Type: Y
+// CHECK: Access: 3
+
+struct C { int i; };
+// CHECK: ---
+// CHECK: KEY: C
+// CHECK: FullyQualifiedName: C
+// CHECK: Name: C
+// CHECK: ID: Member
+// CHECK: Type: int
+// CHECK: Name: C::i
+// CHECK: Access: 3
+// CHECK: ---
+// CHECK: KEY: C::C
+// CHECK: FullyQualifiedName: C::C
+// CHECK: Name: C
+// CHECK: Namespace: C
+
+class D {};
+// CHECK: ---
+// CHECK: KEY: D
+// CHECK: FullyQualifiedName: D
+// CHECK: Name: D
+// CHECK: TagType: 3
+// CHECK: ---
+// CHECK: KEY: D::D
+// CHECK: FullyQualifiedName: D::D
+// CHECK: Name: D
+// CHECK: Namespace: D
+
+class E {
+// CHECK: ---
+// CHECK: KEY: E
+// CHECK: FullyQualifiedName: E
+// CHECK: Name: E
+// CHECK: TagType: 3
+// CHECK: ---
+// CHECK: KEY: E::E
+// CHECK: FullyQualifiedName: E::E
+// CHECK: Name: E
+// CHECK: Namespace: E
+
+public:
+	E() {}
+// CHECK: ---
+// CHECK: KEY: _ZN1EC1Ev
+// CHECK: FullyQualifiedName: E::E
+// CHECK: Name: E
+// CHECK: Namespace: E
+// CHECK: MangledName: _ZN1EC1Ev
+// CHECK: Parent: E
+// CHECK: ID: Return
+// CHECK: Type: void
+// CHECK: Access: 3
+
+	 ~E() {}
+// CHECK: ---
+// CHECK: KEY: _ZN1ED1Ev
+// CHECK: FullyQualifiedName: E::~E
+// CHECK: Name: ~E
+// CHECK: Namespace: E
+// CHECK: MangledName: _ZN1ED1Ev
+// CHECK: Parent: E
+// CHECK: ID: Return
+// CHECK: Type: void
+// CHECK: Access: 3
+
+protected:
+	void ProtectedMethod();
+// CHECK:  ---
+// CHECK: KEY: _ZN1E15ProtectedMethodEv
+// CHECK: FullyQualifiedName: _ZN1E15ProtectedMethodEv
+// CHECK: Name: ProtectedMethod
+// CHECK: Namespace: E
+};
+
+void E::ProtectedMethod() {}
+// CHECK: ---
+// CHECK: KEY: _ZN1E15ProtectedMethodEv
+// CHECK: FullyQualifiedName: E::ProtectedMethod
+// CHECK: Name: ProtectedMethod
+// CHECK: Namespace: E
+// CHECK: MangledName: _ZN1E15ProtectedMethodEv
+// CHECK: Parent: E
+// CHECK: ID: Return
+// CHECK: Type: void
+// CHECK: Access: 3
+// CHECK: Access: 1
+
+class F : virtual private D, public E {};
+// CHECK: ---
+// CHECK: KEY: F
+// CHECK: FullyQualifiedName: F
+// CHECK: Name: F
+// CHECK: TagType: 3
+// CHECK: Parent: class E
+// CHECK: VParent: class D
+// CHECK: ---
+// CHECK: KEY: F::F
+// CHECK: FullyQualifiedName: F::F
+// CHECK: Name: F
+// CHECK: Namespace: F
Index: test/clang-doc/mapper-namespace.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-namespace.cpp
@@ -0,0 +1,70 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc --dump --omit-filenames -doxygen -p %t %t/test.cpp | FileCheck %s
+
+namespace A {
+// CHECK: ---
+// CHECK: KEY: A
+// CHECK: FullyQualifiedName: A
+// CHECK: Name: A
+
+void f() {};
+// CHECK: ---
+// CHECK: KEY: _ZN1A1fEv
+// CHECK: FullyQualifiedName: A::f
+// CHECK: Name: f
+// CHECK: Namespace: A
+// CHECK: MangledName: _ZN1A1fEv
+// CHECK: ID: Return
+// CHECK: Type: void
+// CHECK: Access: 3
+// CHECK: Access: 3
+
+} // A
+
+namespace A {
+// CHECK: ---
+// CHECK: KEY: A
+// CHECK: FullyQualifiedName: A
+// CHECK: Name: A
+
+namespace B {
+// CHECK: ---
+// CHECK: KEY: A::B
+// CHECK: FullyQualifiedName: A::B
+// CHECK: Name: B
+// CHECK: Namespace: A
+
+enum E { X };
+// CHECK: ---
+// CHECK: KEY: A::B::E
+// CHECK: FullyQualifiedName: A::B::E
+// CHECK: Name: E
+// CHECK: Namespace: A::B
+// CHECK: ID: Member
+// CHECK: Type: A::B::X
+// CHECK: Access: 3
+
+E func(int i) { 
+	return X;

Buildbot numbers for the last week of 1/28/2018 - 2/03/2018

2018-02-09 Thread Galina Kistanova via cfe-commits
Hello everyone,

Below are some buildbot numbers for the last week of 1/28/2018 - 2/03/2018.

Please see the same data in attached csv files:

The longest time each builder was red during the week;
"Status change ratio" by active builder (percent of builds that changed the
builder status from greed to red or from red to green);
Count of commits by project;
Number of completed builds, failed builds and average build time for
successful builds per active builder;
Average waiting time for a revision to get build result per active builder
(response time).

Thanks

Galina


The longest time each builder was red during the week:

   buildername   |  was_red
-+--
 libcxx-libcxxabi-x86_64-linux-ubuntu-gcc-tot-latest-std | 100:05:51
 llvm-clang-x86_64-expensive-checks-win  | 83:50:21
 clang-cmake-mipsel  | 68:34:42
 lldb-windows7-android   | 46:54:46
 libcxx-libcxxabi-libunwind-aarch64-linux| 45:47:19
 clang-x64-ninja-win7| 25:14:36
 libcxx-libcxxabi-x86_64-linux-debian| 22:33:58
 libcxx-libcxxabi-libunwind-x86_64-linux-debian  | 22:28:52
 polly-arm-linux | 22:09:11
 polly-amd64-linux   | 21:03:58
 clang-x86_64-linux-selfhost-modules | 21:03:53
 clang-ppc64le-linux-multistage  | 20:24:26
 clang-x86_64-debian-fast| 16:59:07
 clang-cmake-thumbv7-a15-full-sh | 15:45:45
 clang-cuda-build| 15:17:58
 clang-hexagon-elf   | 15:00:42
 clang-cmake-aarch64-global-isel | 14:51:20
 clang-cmake-aarch64-full| 14:50:17
 clang-cmake-aarch64-quick   | 14:47:46
 clang-cmake-thumbv7-a15 | 14:39:51
 clang-cmake-armv7-a15   | 14:38:39
 llvm-hexagon-elf| 14:26:22
 clang-cmake-armv7-a15-selfhost-neon | 14:05:47
 clang-cmake-armv7-a15-full  | 13:50:03
 clang-cmake-armv7-a15-selfhost  | 13:40:56
 lldb-x86_64-darwin-13.4 | 11:34:13
 sanitizer-x86_64-linux-android  | 10:26:18
 lldb-x86_64-ubuntu-14.04-cmake  | 09:54:45
 lldb-x86_64-ubuntu-14.04-android| 09:52:02
 clang-lld-x86_64-2stage | 08:12:04
 llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast| 07:26:30
 sanitizer-ppc64le-linux | 07:17:23
 clang-with-lto-ubuntu   | 06:58:42
 clang-x86_64-linux-selfhost-modules-2   | 06:42:02
 clang-with-thin-lto-ubuntu  | 06:20:30
 llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast  | 06:19:56
 clang-s390x-linux-lnt   | 06:05:57
 clang-s390x-linux-multistage| 05:47:15
 clang-ppc64be-linux-multistage  | 05:22:04
 clang-ppc64le-linux | 05:20:23
 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx2a  | 05:19:14
 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx17  | 05:19:00
 clang-ppc64be-linux | 05:11:49
 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx14  | 05:06:57
 clang-ppc64le-linux-lnt | 05:03:44
 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx11  | 04:54:00
 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx03  | 04:53:42
 clang-s390x-linux   | 03:27:58
 clang-atom-d525-fedora-rel  | 03:26:16
 llvm-mips-linux | 03:20:18
 ubuntu-gcc7.1-werror| 03:07:37
 clang-bpf-build | 03:04:25
 sanitizer-x86_64-linux-bootstrap| 02:56:55
 clang-cmake-aarch64-lld | 02:53:43
 lld-x86_64-win7 | 02:45:34
 sanitizer-windows   | 02:43:22
 lldb-x86-windows-msvc2015   | 02:40:54
 sanitizer-ppc64be-linux | 02:26:18
 sanitizer-x86_64-linux-bootstrap-ubsan  | 02:10:06
 reverse-iteration   | 01:50:21
 sanitizer-x86_64-linux-fast | 01:49:41
 sanitizer-x86_64-linux-bootstrap-msan   | 01:34:37
 

Buildbot numbers for the week of 1/21/2018 - 1/27/2018

2018-02-09 Thread Galina Kistanova via cfe-commits
Hello everyone,

Below are some buildbot numbers for the week of 1/21/2018 - 1/27/2018.

Please see the same data in attached csv files:

The longest time each builder was red during the week;
"Status change ratio" by active builder (percent of builds that changed the
builder status from greed to red or from red to green);
Count of commits by project;
Number of completed builds, failed builds and average build time for
successful builds per active builder;
Average waiting time for a revision to get build result per active builder
(response time).

Thanks

Galina


The longest time each builder was red during the week:

  buildername  | was_red
---+-
 sanitizer-ppc64be-linux   | 47:40:10
 clang-ppc64be-linux-multistage| 47:30:29
 clang-ppc64be-linux   | 44:45:44
 clang-s390x-linux-multistage  | 35:42:00
 lldb-windows7-android | 30:15:21
 clang-ppc64le-linux-multistage| 27:49:42
 lldb-x86_64-ubuntu-14.04-android  | 25:51:31
 lldb-x86_64-ubuntu-14.04-cmake| 25:22:41
 clang-x86_64-linux-selfhost-modules   | 23:58:46
 clang-x86_64-linux-selfhost-modules-2 | 23:49:12
 libcxx-libcxxabi-singlethreaded-x86_64-linux-debian   | 22:09:49
 libcxx-libcxxabi-x86_64-linux-debian  | 21:53:34
 libcxx-libcxxabi-x86_64-linux-debian-noexceptions | 21:36:00
 libcxx-libcxxabi-libunwind-x86_64-linux-debian| 21:20:43
 clang-cmake-armv7-a15-selfhost-neon   | 20:34:59
 clang-cmake-armv7-a15-selfhost| 19:45:46
 clang-x86-windows-msvc2015| 16:27:26
 clang-cmake-thumbv7-a15-full-sh   | 13:18:15
 llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast  | 11:36:24
 llvm-clang-x86_64-expensive-checks-win| 11:34:43
 clang-x64-ninja-win7  | 11:17:06
 clang-cmake-aarch64-full  | 10:59:57
 clang-cmake-armv7-a15-full| 10:59:52
 ubuntu-gcc7.1-werror  | 10:06:17
 clang-lld-x86_64-2stage   | 10:05:08
 clang-bpf-build   | 08:31:13
 clang-native-arm-lnt  | 07:59:14
 clang-cmake-armv7-a15 | 07:26:23
 clang-cmake-thumbv7-a15   | 07:26:10
 lldb-x86_64-ubuntu-14.04-buildserver  | 06:26:47
 lldb-x86-windows-msvc2015 | 06:14:00
 sanitizer-ppc64le-linux   | 06:09:49
 libcxx-libcxxabi-x86_64-linux-ubuntu-ubsan| 05:55:30
 sanitizer-windows | 05:54:45
 libcxx-libcxxabi-x86_64-linux-ubuntu-msan | 05:53:38
 clang-s390x-linux-lnt | 04:41:26
 clang-s390x-linux | 04:38:37
 clang-with-thin-lto-ubuntu| 04:30:25
 clang-x86_64-debian-fast  | 04:23:07
 polly-amd64-linux | 04:06:42
 clang-with-lto-ubuntu | 04:01:10
 llvm-mips-linux   | 03:57:51
 clang-ppc64le-linux-lnt   | 03:37:08
 clang-cmake-x86_64-avx2-linux | 03:24:47
 sanitizer-x86_64-linux| 03:17:49
 libcxx-libcxxabi-x86_64-linux-ubuntu-tsan | 03:06:34
 libcxx-libcxxabi-libunwind-x86_64-linux-ubuntu| 03:06:30
 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx2a| 03:06:19
 sanitizer-x86_64-linux-bootstrap  | 03:00:13
 libcxx-libcxxabi-x86_64-linux-ubuntu-asan | 03:00:01
 libcxx-libcxxabi-x86_64-linux-ubuntu-32bit| 02:59:11
 clang-atom-d525-fedora-rel| 02:59:07
 clang-cmake-aarch64-lld   | 02:57:57
 libcxx-libcxxabi-libunwind-aarch64-linux  | 02:46:28
 clang-cmake-aarch64-global-isel   | 02:45:52
 clang-cmake-aarch64-quick | 02:45:36
 clang-ppc64le-linux   | 02:42:17
 sanitizer-x86_64-linux-fuzzer | 02:33:33
 sanitizer-x86_64-linux-bootstrap-msan | 02:32:08
 llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast| 02:29:46
 clang-cuda-build  | 02:27:17
 clang-x86_64-linux-abi-test   | 02:24:48
 lldb-amd64-ninja-netbsd8  | 02:18:11
 libcxx-libcxxabi-libunwind-arm-linux  | 02:07:25
 

[PATCH] D42310: Formalize FreeBSD support of compiler rt

2018-02-09 Thread Tom Rix via Phabricator via cfe-commits
trixirt added a comment.

I think it is overkill to look for fbsd 8, it was eol-ed 2015, and 9 in 2016.
A native build of clang 7 on fbsd 8 would be difficult to pull off,  needing at 
least 1-3 intermediate clang's/gcc's


Repository:
  rC Clang

https://reviews.llvm.org/D42310



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


[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr

2018-02-09 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL324790: [analyzer] Add missing pre-post-statement callbacks 
for OffsetOfExpr. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D42300?vs=133421=133721#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D42300

Files:
  cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
  cfe/trunk/test/Analysis/Inputs/system-header-simulator.h
  cfe/trunk/test/Analysis/offsetofexpr-callback.c


Index: cfe/trunk/test/Analysis/Inputs/system-header-simulator.h
===
--- cfe/trunk/test/Analysis/Inputs/system-header-simulator.h
+++ cfe/trunk/test/Analysis/Inputs/system-header-simulator.h
@@ -110,4 +110,6 @@
 #ifndef NULL
 #define __DARWIN_NULL 0
 #define NULL __DARWIN_NULL
-#endif
\ No newline at end of file
+#endif
+
+#define offsetof(t, d) __builtin_offsetof(t, d)
\ No newline at end of file
Index: cfe/trunk/test/Analysis/offsetofexpr-callback.c
===
--- cfe/trunk/test/Analysis/offsetofexpr-callback.c
+++ cfe/trunk/test/Analysis/offsetofexpr-callback.c
@@ -0,0 +1,13 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder 
-analyzer-config 
debug.AnalysisOrder:PreStmtOffsetOfExpr=true,debug.AnalysisOrder:PostStmtOffsetOfExpr=true
 %s 2>&1 | FileCheck %s
+#include "Inputs/system-header-simulator.h"
+
+struct S {
+  char c;
+};
+
+void test() {
+  offsetof(struct S, c); 
+}
+
+// CHECK: PreStmt
+// CHECK-NEXT: PostStmt
\ No newline at end of file
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1543,12 +1543,19 @@
   Bldr.addNodes(Dst);
   break;
 
-case Stmt::OffsetOfExprClass:
+case Stmt::OffsetOfExprClass: {
   Bldr.takeNodes(Pred);
-  VisitOffsetOfExpr(cast(S), Pred, Dst);
+  ExplodedNodeSet PreVisit;
+  getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+
+  ExplodedNodeSet PostVisit;
+  for (ExplodedNode *Node : PreVisit)
+VisitOffsetOfExpr(cast(S), Node, PostVisit);
+
+  getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
   Bldr.addNodes(Dst);
   break;
-
+}
 case Stmt::UnaryExprOrTypeTraitExprClass:
   Bldr.takeNodes(Pred);
   VisitUnaryExprOrTypeTraitExpr(cast(S),
Index: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
@@ -33,6 +33,8 @@
  check::PostStmt,
  check::PreStmt,
  check::PostStmt,
+ check::PreStmt,
+ check::PostStmt,
  check::PreCall,
  check::PostCall,
  check::NewAllocator,
@@ -91,6 +93,16 @@
   llvm::errs() << "PostStmt\n";
   }
 
+  void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext ) const {
+if (isCallbackEnabled(C, "PreStmtOffsetOfExpr"))
+  llvm::errs() << "PreStmt\n";
+  }
+
+  void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext ) const {
+if (isCallbackEnabled(C, "PostStmtOffsetOfExpr"))
+  llvm::errs() << "PostStmt\n";
+  }
+
   void checkPreCall(const CallEvent , CheckerContext ) const {
 if (isCallbackEnabled(C, "PreCall")) {
   llvm::errs() << "PreCall";


Index: cfe/trunk/test/Analysis/Inputs/system-header-simulator.h
===
--- cfe/trunk/test/Analysis/Inputs/system-header-simulator.h
+++ cfe/trunk/test/Analysis/Inputs/system-header-simulator.h
@@ -110,4 +110,6 @@
 #ifndef NULL
 #define __DARWIN_NULL 0
 #define NULL __DARWIN_NULL
-#endif
\ No newline at end of file
+#endif
+
+#define offsetof(t, d) __builtin_offsetof(t, d)
\ No newline at end of file
Index: cfe/trunk/test/Analysis/offsetofexpr-callback.c
===
--- cfe/trunk/test/Analysis/offsetofexpr-callback.c
+++ cfe/trunk/test/Analysis/offsetofexpr-callback.c
@@ -0,0 +1,13 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PreStmtOffsetOfExpr=true,debug.AnalysisOrder:PostStmtOffsetOfExpr=true %s 2>&1 | FileCheck %s
+#include "Inputs/system-header-simulator.h"
+
+struct S {
+  char c;
+};
+
+void test() {
+  offsetof(struct S, c); 
+}
+
+// CHECK: PreStmt
+// CHECK-NEXT: PostStmt
\ No newline at end of file
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp

r324790 - [analyzer] Add missing pre-post-statement callbacks for OffsetOfExpr.

2018-02-09 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Fri Feb  9 16:55:49 2018
New Revision: 324790

URL: http://llvm.org/viewvc/llvm-project?rev=324790=rev
Log:
[analyzer] Add missing pre-post-statement callbacks for OffsetOfExpr.

This expression may or may not be evaluated in compile time, so tracking the
result symbol is of potential interest. However, run-time offsetof is not yet
supported by the analyzer, so for now this callback is only there to assist
future implementation.

Patch by Henry Wong!

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

Added:
cfe/trunk/test/Analysis/offsetofexpr-callback.c
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/test/Analysis/Inputs/system-header-simulator.h

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp?rev=324790=324789=324790=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp Fri Feb  9 
16:55:49 2018
@@ -33,6 +33,8 @@ class AnalysisOrderChecker
  check::PostStmt,
  check::PreStmt,
  check::PostStmt,
+ check::PreStmt,
+ check::PostStmt,
  check::PreCall,
  check::PostCall,
  check::NewAllocator,
@@ -91,6 +93,16 @@ public:
   llvm::errs() << "PostStmt\n";
   }
 
+  void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext ) const {
+if (isCallbackEnabled(C, "PreStmtOffsetOfExpr"))
+  llvm::errs() << "PreStmt\n";
+  }
+
+  void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext ) const {
+if (isCallbackEnabled(C, "PostStmtOffsetOfExpr"))
+  llvm::errs() << "PostStmt\n";
+  }
+
   void checkPreCall(const CallEvent , CheckerContext ) const {
 if (isCallbackEnabled(C, "PreCall")) {
   llvm::errs() << "PreCall";

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=324790=324789=324790=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Feb  9 16:55:49 2018
@@ -1543,12 +1543,19 @@ void ExprEngine::Visit(const Stmt *S, Ex
   Bldr.addNodes(Dst);
   break;
 
-case Stmt::OffsetOfExprClass:
+case Stmt::OffsetOfExprClass: {
   Bldr.takeNodes(Pred);
-  VisitOffsetOfExpr(cast(S), Pred, Dst);
+  ExplodedNodeSet PreVisit;
+  getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+
+  ExplodedNodeSet PostVisit;
+  for (ExplodedNode *Node : PreVisit)
+VisitOffsetOfExpr(cast(S), Node, PostVisit);
+
+  getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
   Bldr.addNodes(Dst);
   break;
-
+}
 case Stmt::UnaryExprOrTypeTraitExprClass:
   Bldr.takeNodes(Pred);
   VisitUnaryExprOrTypeTraitExpr(cast(S),

Modified: cfe/trunk/test/Analysis/Inputs/system-header-simulator.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/system-header-simulator.h?rev=324790=324789=324790=diff
==
--- cfe/trunk/test/Analysis/Inputs/system-header-simulator.h (original)
+++ cfe/trunk/test/Analysis/Inputs/system-header-simulator.h Fri Feb  9 
16:55:49 2018
@@ -110,4 +110,6 @@ void _Exit(int status) __attribute__ ((_
 #ifndef NULL
 #define __DARWIN_NULL 0
 #define NULL __DARWIN_NULL
-#endif
\ No newline at end of file
+#endif
+
+#define offsetof(t, d) __builtin_offsetof(t, d)
\ No newline at end of file

Added: cfe/trunk/test/Analysis/offsetofexpr-callback.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/offsetofexpr-callback.c?rev=324790=auto
==
--- cfe/trunk/test/Analysis/offsetofexpr-callback.c (added)
+++ cfe/trunk/test/Analysis/offsetofexpr-callback.c Fri Feb  9 16:55:49 2018
@@ -0,0 +1,13 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder 
-analyzer-config 
debug.AnalysisOrder:PreStmtOffsetOfExpr=true,debug.AnalysisOrder:PostStmtOffsetOfExpr=true
 %s 2>&1 | FileCheck %s
+#include "Inputs/system-header-simulator.h"
+
+struct S {
+  char c;
+};
+
+void test() {
+  offsetof(struct S, c); 
+}
+
+// CHECK: PreStmt
+// CHECK-NEXT: PostStmt
\ No newline at end of file


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


[PATCH] D42745: [analyzer] Add support for __builtin_constant_p to BuiltinFunctionChecker

2018-02-09 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL324789: [analyzer] Add support for __builtin_constant_p. 
(authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D42745?vs=133447=133720#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D42745

Files:
  cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
  cfe/trunk/test/Analysis/builtin-functions.cpp


Index: cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -96,7 +96,8 @@
 return true;
   }
 
-  case Builtin::BI__builtin_object_size: {
+  case Builtin::BI__builtin_object_size:
+  case Builtin::BI__builtin_constant_p: {
 // This must be resolvable at compile time, so we defer to the constant
 // evaluator for a value.
 SVal V = UnknownVal();
Index: cfe/trunk/test/Analysis/builtin-functions.cpp
===
--- cfe/trunk/test/Analysis/builtin-functions.cpp
+++ cfe/trunk/test/Analysis/builtin-functions.cpp
@@ -64,3 +64,20 @@
 // We give up the analysis on this path.
   }
 }
+
+void test_constant_p() {
+  int i = 1;
+  const int j = 2;
+  constexpr int k = 3;
+  clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // 
expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning 
{{FALSE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning 
{{TRUE}}
+}


Index: cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -96,7 +96,8 @@
 return true;
   }
 
-  case Builtin::BI__builtin_object_size: {
+  case Builtin::BI__builtin_object_size:
+  case Builtin::BI__builtin_constant_p: {
 // This must be resolvable at compile time, so we defer to the constant
 // evaluator for a value.
 SVal V = UnknownVal();
Index: cfe/trunk/test/Analysis/builtin-functions.cpp
===
--- cfe/trunk/test/Analysis/builtin-functions.cpp
+++ cfe/trunk/test/Analysis/builtin-functions.cpp
@@ -64,3 +64,20 @@
 // We give up the analysis on this path.
   }
 }
+
+void test_constant_p() {
+  int i = 1;
+  const int j = 2;
+  constexpr int k = 3;
+  clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}}
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42745: [analyzer] Add support for __builtin_constant_p to BuiltinFunctionChecker

2018-02-09 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC324789: [analyzer] Add support for __builtin_constant_p. 
(authored by dergachev, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D42745

Files:
  lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
  test/Analysis/builtin-functions.cpp


Index: test/Analysis/builtin-functions.cpp
===
--- test/Analysis/builtin-functions.cpp
+++ test/Analysis/builtin-functions.cpp
@@ -64,3 +64,20 @@
 // We give up the analysis on this path.
   }
 }
+
+void test_constant_p() {
+  int i = 1;
+  const int j = 2;
+  constexpr int k = 3;
+  clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // 
expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning 
{{FALSE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning 
{{TRUE}}
+}
Index: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -96,7 +96,8 @@
 return true;
   }
 
-  case Builtin::BI__builtin_object_size: {
+  case Builtin::BI__builtin_object_size:
+  case Builtin::BI__builtin_constant_p: {
 // This must be resolvable at compile time, so we defer to the constant
 // evaluator for a value.
 SVal V = UnknownVal();


Index: test/Analysis/builtin-functions.cpp
===
--- test/Analysis/builtin-functions.cpp
+++ test/Analysis/builtin-functions.cpp
@@ -64,3 +64,20 @@
 // We give up the analysis on this path.
   }
 }
+
+void test_constant_p() {
+  int i = 1;
+  const int j = 2;
+  constexpr int k = 3;
+  clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}}
+}
Index: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -96,7 +96,8 @@
 return true;
   }
 
-  case Builtin::BI__builtin_object_size: {
+  case Builtin::BI__builtin_object_size:
+  case Builtin::BI__builtin_constant_p: {
 // This must be resolvable at compile time, so we defer to the constant
 // evaluator for a value.
 SVal V = UnknownVal();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r324789 - [analyzer] Add support for __builtin_constant_p.

2018-02-09 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Fri Feb  9 16:51:47 2018
New Revision: 324789

URL: http://llvm.org/viewvc/llvm-project?rev=324789=rev
Log:
[analyzer] Add support for __builtin_constant_p.

This builtin is evaluated in compile time. But in the analyzer we don't yet
automagically evaluate all calls that can be evaluated in compile time.

Patch by Felix Kostenzer!

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
cfe/trunk/test/Analysis/builtin-functions.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp?rev=324789=324788=324789=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp Fri Feb  9 
16:51:47 2018
@@ -96,7 +96,8 @@ bool BuiltinFunctionChecker::evalCall(co
 return true;
   }
 
-  case Builtin::BI__builtin_object_size: {
+  case Builtin::BI__builtin_object_size:
+  case Builtin::BI__builtin_constant_p: {
 // This must be resolvable at compile time, so we defer to the constant
 // evaluator for a value.
 SVal V = UnknownVal();

Modified: cfe/trunk/test/Analysis/builtin-functions.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/builtin-functions.cpp?rev=324789=324788=324789=diff
==
--- cfe/trunk/test/Analysis/builtin-functions.cpp (original)
+++ cfe/trunk/test/Analysis/builtin-functions.cpp Fri Feb  9 16:51:47 2018
@@ -64,3 +64,20 @@ void g(int i) {
 // We give up the analysis on this path.
   }
 }
+
+void test_constant_p() {
+  int i = 1;
+  const int j = 2;
+  constexpr int k = 3;
+  clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning 
{{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // 
expected-warning {{TRUE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning 
{{FALSE}}
+  clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning 
{{TRUE}}
+}


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


[PATCH] D43149: [analyzer] Fix a crash on destroying a temporary array.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 133718.
NoQ added a comment.

> And even then, calling a destructor of a single array element does not 
> invalidate the whole array for us, because destructors are `const` (unless 
> there are mutable members). So we'd have to do this manually later as well.

Hmm, no, we don't. Because, well, destructors are `const`, so they won't change 
the contents of the array, so there's no need to invalidate in the first place.


https://reviews.llvm.org/D43149

Files:
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/Analysis/temporaries.cpp


Index: test/Analysis/temporaries.cpp
===
--- test/Analysis/temporaries.cpp
+++ test/Analysis/temporaries.cpp
@@ -6,6 +6,8 @@
 extern bool clang_analyzer_warnIfReached();
 void clang_analyzer_checkInlined(bool);
 
+#include "Inputs/system-header-simulator-cxx.h";
+
 struct Trivial {
   Trivial(int x) : value(x) {}
   int value;
@@ -857,3 +859,17 @@
   }
 }
 } // namespace test_match_constructors_and_destructors
+
+#if __cplusplus >= 201103L
+namespace temporary_list_crash {
+class C {
+public:
+  C() {}
+  ~C() {}
+};
+
+void test() {
+  std::initializer_list{C(), C()}; // no-crash
+}
+} // namespace temporary_list_crash
+#endif // C++11
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -957,18 +957,31 @@
   }
   StmtBldr.generateNode(D.getBindTemporaryExpr(), Pred, State);
 
-  QualType varType = D.getBindTemporaryExpr()->getSubExpr()->getType();
+  QualType T = D.getBindTemporaryExpr()->getSubExpr()->getType();
   // FIXME: Currently CleanDtorState can be empty here due to temporaries being
   // bound to default parameters.
   assert(CleanDtorState.size() <= 1);
   ExplodedNode *CleanPred =
   CleanDtorState.empty() ? Pred : *CleanDtorState.begin();
 
   EvalCallOptions CallOpts;
   CallOpts.IsTemporaryCtorOrDtor = true;
-  if (!MR)
+  if (!MR) {
 CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
-  VisitCXXDestructor(varType, MR, D.getBindTemporaryExpr(),
+
+// If we have no MR, we still need to unwrap the array to avoid destroying
+// the whole array at once. Regardless, we'd eventually need to model array
+// destructors properly, element-by-element.
+while (const ArrayType *AT = getContext().getAsArrayType(T)) {
+  T = AT->getElementType();
+  CallOpts.IsArrayCtorOrDtor = true;
+}
+  } else {
+// We'd eventually need to makeZeroElementRegion() trick here,
+// but for now we don't have the respective construction contexts,
+// so MR would always be null in this case. Do nothing for now.
+  }
+  VisitCXXDestructor(T, MR, D.getBindTemporaryExpr(),
  /*IsBase=*/false, CleanPred, Dst, CallOpts);
 }
 


Index: test/Analysis/temporaries.cpp
===
--- test/Analysis/temporaries.cpp
+++ test/Analysis/temporaries.cpp
@@ -6,6 +6,8 @@
 extern bool clang_analyzer_warnIfReached();
 void clang_analyzer_checkInlined(bool);
 
+#include "Inputs/system-header-simulator-cxx.h";
+
 struct Trivial {
   Trivial(int x) : value(x) {}
   int value;
@@ -857,3 +859,17 @@
   }
 }
 } // namespace test_match_constructors_and_destructors
+
+#if __cplusplus >= 201103L
+namespace temporary_list_crash {
+class C {
+public:
+  C() {}
+  ~C() {}
+};
+
+void test() {
+  std::initializer_list{C(), C()}; // no-crash
+}
+} // namespace temporary_list_crash
+#endif // C++11
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -957,18 +957,31 @@
   }
   StmtBldr.generateNode(D.getBindTemporaryExpr(), Pred, State);
 
-  QualType varType = D.getBindTemporaryExpr()->getSubExpr()->getType();
+  QualType T = D.getBindTemporaryExpr()->getSubExpr()->getType();
   // FIXME: Currently CleanDtorState can be empty here due to temporaries being
   // bound to default parameters.
   assert(CleanDtorState.size() <= 1);
   ExplodedNode *CleanPred =
   CleanDtorState.empty() ? Pred : *CleanDtorState.begin();
 
   EvalCallOptions CallOpts;
   CallOpts.IsTemporaryCtorOrDtor = true;
-  if (!MR)
+  if (!MR) {
 CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
-  VisitCXXDestructor(varType, MR, D.getBindTemporaryExpr(),
+
+// If we have no MR, we still need to unwrap the array to avoid destroying
+// the whole array at once. Regardless, we'd eventually need to model array
+// destructors properly, element-by-element.
+while (const ArrayType *AT = getContext().getAsArrayType(T)) {
+  T = AT->getElementType();
+  CallOpts.IsArrayCtorOrDtor = true;
+}
+  } else {
+// We'd eventually need to makeZeroElementRegion() trick here,
+// but for now we 

[PATCH] D41102: Setup clang-doc frontend framework

2018-02-09 Thread Julie Hockett via Phabricator via cfe-commits
juliehockett updated this revision to Diff 133714.
juliehockett marked 6 inline comments as done.
juliehockett added a comment.

1. Implementing the bitstream decoder (and fixing the encoder)
2. Setting up new tests for the mapper output
3. Fixing comments


https://reviews.llvm.org/D41102

Files:
  CMakeLists.txt
  clang-doc/CMakeLists.txt
  clang-doc/ClangDoc.cpp
  clang-doc/ClangDoc.h
  clang-doc/ClangDocBinary.cpp
  clang-doc/ClangDocBinary.h
  clang-doc/ClangDocMapper.cpp
  clang-doc/ClangDocMapper.h
  clang-doc/ClangDocRepresentation.h
  clang-doc/tool/CMakeLists.txt
  clang-doc/tool/ClangDocMain.cpp
  docs/clang-doc.rst
  test/CMakeLists.txt
  test/clang-doc/Inputs/enum_test.cpp
  test/clang-doc/Inputs/namespace_test.cpp
  test/clang-doc/Inputs/record_test.cpp
  test/clang-doc/mapper-namespace.cpp
  test/clang-doc/mapper-type.cpp

Index: test/clang-doc/mapper-type.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-type.cpp
@@ -0,0 +1,137 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc  --dump --omit-filenames -doxygen -p %t %t/test.cpp | FileCheck %s
+
+union A { int X; int Y; };
+// CHECK: ---
+// CHECK: KEY: A
+// CHECK: FullyQualifiedName: A
+// CHECK: Name: A
+// CHECK: TagType: 2
+// CHECK: ID: Member
+// CHECK: Type: int
+// CHECK: Name: A::X
+// CHECK: Access: 3
+// CHECK: ID: Member
+// CHECK: Type: int
+// CHECK: Name: A::Y
+// CHECK: Access: 3
+// CHECK: ---
+// CHECK: KEY: A::A
+// CHECK: FullyQualifiedName: A::A
+// CHECK: Name: A
+// CHECK: Namespace: A
+
+enum B { X, Y };
+// CHECK: ---
+// CHECK: KEY: B
+// CHECK: FullyQualifiedName: B
+// CHECK: Name: B
+// CHECK: ID: Member
+// CHECK: Type: X
+// CHECK: Access: 3
+// CHECK: ID: Member
+// CHECK: Type: Y
+// CHECK: Access: 3
+
+struct C { int i; };
+// CHECK: ---
+// CHECK: KEY: C
+// CHECK: FullyQualifiedName: C
+// CHECK: Name: C
+// CHECK: ID: Member
+// CHECK: Type: int
+// CHECK: Name: C::i
+// CHECK: Access: 3
+// CHECK: ---
+// CHECK: KEY: C::C
+// CHECK: FullyQualifiedName: C::C
+// CHECK: Name: C
+// CHECK: Namespace: C
+
+class D {};
+// CHECK: ---
+// CHECK: KEY: D
+// CHECK: FullyQualifiedName: D
+// CHECK: Name: D
+// CHECK: TagType: 3
+// CHECK: ---
+// CHECK: KEY: D::D
+// CHECK: FullyQualifiedName: D::D
+// CHECK: Name: D
+// CHECK: Namespace: D
+
+class E {
+// CHECK: ---
+// CHECK: KEY: E
+// CHECK: FullyQualifiedName: E
+// CHECK: Name: E
+// CHECK: TagType: 3
+// CHECK: ---
+// CHECK: KEY: E::E
+// CHECK: FullyQualifiedName: E::E
+// CHECK: Name: E
+// CHECK: Namespace: E
+
+public:
+	E() {}
+// CHECK: ---
+// CHECK: KEY: _ZN1EC1Ev
+// CHECK: FullyQualifiedName: E::E
+// CHECK: Name: E
+// CHECK: Namespace: E
+// CHECK: MangledName: _ZN1EC1Ev
+// CHECK: Parent: E
+// CHECK: ID: Return
+// CHECK: Type: void
+// CHECK: Access: 3
+
+	 ~E() {}
+// CHECK: ---
+// CHECK: KEY: _ZN1ED1Ev
+// CHECK: FullyQualifiedName: E::~E
+// CHECK: Name: ~E
+// CHECK: Namespace: E
+// CHECK: MangledName: _ZN1ED1Ev
+// CHECK: Parent: E
+// CHECK: ID: Return
+// CHECK: Type: void
+// CHECK: Access: 3
+
+protected:
+	void ProtectedMethod();
+// CHECK:  ---
+// CHECK: KEY: _ZN1E15ProtectedMethodEv
+// CHECK: FullyQualifiedName: _ZN1E15ProtectedMethodEv
+// CHECK: Name: ProtectedMethod
+// CHECK: Namespace: E
+};
+
+void E::ProtectedMethod() {}
+// CHECK: ---
+// CHECK: KEY: _ZN1E15ProtectedMethodEv
+// CHECK: FullyQualifiedName: E::ProtectedMethod
+// CHECK: Name: ProtectedMethod
+// CHECK: Namespace: E
+// CHECK: MangledName: _ZN1E15ProtectedMethodEv
+// CHECK: Parent: E
+// CHECK: ID: Return
+// CHECK: Type: void
+// CHECK: Access: 3
+// CHECK: Access: 1
+
+class F : virtual private D, public E {};
+// CHECK: ---
+// CHECK: KEY: F
+// CHECK: FullyQualifiedName: F
+// CHECK: Name: F
+// CHECK: TagType: 3
+// CHECK: Parent: class E
+// CHECK: VParent: class D
+// CHECK: ---
+// CHECK: KEY: F::F
+// CHECK: FullyQualifiedName: F::F
+// CHECK: Name: F
+// CHECK: Namespace: F
Index: test/clang-doc/mapper-namespace.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-namespace.cpp
@@ -0,0 +1,70 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc --dump --omit-filenames -doxygen -p %t %t/test.cpp | FileCheck %s
+
+namespace A {
+// CHECK: ---
+// CHECK: KEY: A
+// CHECK: FullyQualifiedName: A
+// CHECK: Name: A
+
+void f() {};
+// CHECK: ---
+// CHECK: KEY: _ZN1A1fEv
+// CHECK: FullyQualifiedName: A::f
+// CHECK: Name: f
+// CHECK: Namespace: A
+// CHECK: MangledName: _ZN1A1fEv
+// CHECK: ID: Return
+// CHECK: Type: void
+// CHECK: Access: 3
+// CHECK: Access: 3
+
+} // A
+
+namespace A {
+// CHECK: ---
+// CHECK: KEY: A
+// CHECK: FullyQualifiedName: A
+// CHECK: Name: A
+
+namespace B {
+// CHECK: ---
+// CHECK: KEY: A::B
+// CHECK: FullyQualifiedName: A::B
+// CHECK: 

[PATCH] D43149: [analyzer] Fix a crash on destroying a temporary array.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet.
Herald added subscribers: cfe-commits, rnkovacs.

Tried to actually run the analyzer with temporary destructor support on some 
real code, found two crashes for now - https://reviews.llvm.org/D43144 and this 
one. In this example, a temporary of type `C[2]` is constructed in the context 
of `InitListExpr` within `CXXBindTemporaryExpr`:

  `-ExprWithCleanups 0x7f82b9020c28  
'std::initializer_list':'std::initializer_list'
`-CXXFunctionalCastExpr 0x7f82b9020c00  
'std::initializer_list':'std::initializer_list' 
functional cast to std::initializer_list 
  `-CXXStdInitializerListExpr 0x7f82ba0258f8  
'std::initializer_list':'std::initializer_list'
`-MaterializeTemporaryExpr 0x7f82ba0258e0  'const 
temporary_list_crash::C [2]' xvalue
  `-CXXBindTemporaryExpr 0x7f82ba0258c0  'const 
temporary_list_crash::C [2]' (CXXTemporary 0x7f82ba0258b8)*** <=== THIS ONE 
***
`-InitListExpr 0x7f82ba025748  'const 
temporary_list_crash::C [2]'
  |-CXXConstructExpr 0x7f82ba025818  'const 
temporary_list_crash::C' 'void (const temporary_list_crash::C &) noexcept' 
elidable
  | `-MaterializeTemporaryExpr 0x7f82ba0257b0  
'const temporary_list_crash::C' lvalue
  |   `-ImplicitCastExpr 0x7f82ba025798  'const 
temporary_list_crash::C' 
  | `-CXXBindTemporaryExpr 0x7f82ba024ae8  
'temporary_list_crash::C' (CXXTemporary 0x7f82ba024ae0)
  |   `-CXXTemporaryObjectExpr 0x7f82ba024aa8  
'temporary_list_crash::C' 'void ()'
  `-CXXConstructExpr 0x7f82ba025880  'const 
temporary_list_crash::C' 'void (const temporary_list_crash::C &) noexcept' 
elidable
`-MaterializeTemporaryExpr 0x7f82ba025868  
'const temporary_list_crash::C' lvalue
  `-ImplicitCastExpr 0x7f82ba025850  'const 
temporary_list_crash::C' 
`-CXXBindTemporaryExpr 0x7f82ba024b58  
'temporary_list_crash::C' (CXXTemporary 0x7f82ba024b50)
  `-CXXTemporaryObjectExpr 0x7f82ba024b18  
'temporary_list_crash::C' 'void ()'

We'd have to actually support this case eventually, but for now do the trick 
that we've always did: unwrap the array type and pretend we're destroying a 
single object. Once we have the construction context provided for this 
constructor, we'd have the region here, and in this case we'd also need to 
construct `ElementRegion` as part of this trick. And even then, calling a 
destructor of a single array element does not invalidate the whole array for 
us, because destructors are `const` (unless there are mutable members). So we'd 
have to do this manually later as well.


Repository:
  rC Clang

https://reviews.llvm.org/D43149

Files:
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/Analysis/temporaries.cpp


Index: test/Analysis/temporaries.cpp
===
--- test/Analysis/temporaries.cpp
+++ test/Analysis/temporaries.cpp
@@ -6,6 +6,8 @@
 extern bool clang_analyzer_warnIfReached();
 void clang_analyzer_checkInlined(bool);
 
+#include "Inputs/system-header-simulator-cxx.h";
+
 struct Trivial {
   Trivial(int x) : value(x) {}
   int value;
@@ -857,3 +859,17 @@
   }
 }
 } // namespace test_match_constructors_and_destructors
+
+#if __cplusplus >= 201103L
+namespace temporary_list_crash {
+class C {
+public:
+  C() {}
+  ~C() {}
+};
+
+void test() {
+  std::initializer_list{C(), C()}; // no-crash
+}
+} // namespace temporary_list_crash
+#endif // C++11
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -957,18 +957,37 @@
   }
   StmtBldr.generateNode(D.getBindTemporaryExpr(), Pred, State);
 
-  QualType varType = D.getBindTemporaryExpr()->getSubExpr()->getType();
+  QualType T = D.getBindTemporaryExpr()->getSubExpr()->getType();
   // FIXME: Currently CleanDtorState can be empty here due to temporaries being
   // bound to default parameters.
   assert(CleanDtorState.size() <= 1);
   ExplodedNode *CleanPred =
   CleanDtorState.empty() ? Pred : *CleanDtorState.begin();
 
   EvalCallOptions CallOpts;
   CallOpts.IsTemporaryCtorOrDtor = true;
-  if (!MR)
+  if (!MR) {
 CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
-  VisitCXXDestructor(varType, MR, D.getBindTemporaryExpr(),
+
+// If we have no MR, we still need to unwrap the array to avoid destroying
+// the whole array at once. Regardless, we'd eventually need to model array
+// destructors properly, element-by-element.
+while 

r324785 - [analyzer] Introduce statistics for the total number of visited basic blocks

2018-02-09 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Feb  9 15:37:47 2018
New Revision: 324785

URL: http://llvm.org/viewvc/llvm-project?rev=324785=rev
Log:
[analyzer] Introduce statistics for the total number of visited basic blocks

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=324785=324784=324785=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Fri Feb  9 
15:37:47 2018
@@ -57,6 +57,8 @@ STATISTIC(NumFunctionsAnalyzed,
   "with inlining turned on).");
 STATISTIC(NumBlocksInAnalyzedFunctions,
   "The # of basic blocks in the analyzed functions.");
+STATISTIC(NumVisitedBlocksInAnalyzedFunctions,
+  "The # of visited basic blocks in the analyzed functions.");
 STATISTIC(PercentReachableBlocks, "The % of reachable basic blocks.");
 STATISTIC(MaxCFGSize, "The maximum number of basic blocks in a function.");
 
@@ -565,6 +567,8 @@ void AnalysisConsumer::HandleTranslation
 
   // Count how many basic blocks we have not covered.
   NumBlocksInAnalyzedFunctions = FunctionSummaries.getTotalNumBasicBlocks();
+  NumVisitedBlocksInAnalyzedFunctions =
+  FunctionSummaries.getTotalNumVisitedBasicBlocks();
   if (NumBlocksInAnalyzedFunctions > 0)
 PercentReachableBlocks =
   (FunctionSummaries.getTotalNumVisitedBasicBlocks() * 100) /


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


[PATCH] D43148: Adding msan support for FreeBSD

2018-02-09 Thread David CARLIER via Phabricator via cfe-commits
devnexen created this revision.
devnexen added a reviewer: krytarowski.
devnexen created this object with visibility "All Users".
Herald added subscribers: cfe-commits, emaste.

Enabling memory sanitiser for X86_64 arch only. To match the sanitiser 
counterpart.


Repository:
  rC Clang

https://reviews.llvm.org/D43148

Files:
  FreeBSD.cpp


Index: FreeBSD.cpp
===
--- FreeBSD.cpp
+++ FreeBSD.cpp
@@ -394,6 +394,8 @@
 Res |= SanitizerKind::SafeStack;
 Res |= SanitizerKind::Fuzzer;
 Res |= SanitizerKind::FuzzerNoLink;
+if (IsX86_64)
+Res |= SanitizerKind::Memory;
   }
   return Res;
 }


Index: FreeBSD.cpp
===
--- FreeBSD.cpp
+++ FreeBSD.cpp
@@ -394,6 +394,8 @@
 Res |= SanitizerKind::SafeStack;
 Res |= SanitizerKind::Fuzzer;
 Res |= SanitizerKind::FuzzerNoLink;
+if (IsX86_64)
+Res |= SanitizerKind::Memory;
   }
   return Res;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42458: [NFC] Extract method to SourceManager for traversing the macro "stack"

2018-02-09 Thread George Karpenkov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC324780: [NFC] Extract method to SourceManager for traversing 
the macro stack (authored by george.karpenkov, committed by ).
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D42458

Files:
  include/clang/Basic/SourceManager.h
  lib/Basic/SourceManager.cpp
  lib/Edit/Commit.cpp
  lib/Sema/SemaChecking.cpp


Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -9357,11 +9357,8 @@
   // Venture through the macro stacks to get to the source of macro arguments.
   // The new location is a better location than the complete location that was
   // passed in.
-  while (S.SourceMgr.isMacroArgExpansion(Loc))
-Loc = S.SourceMgr.getImmediateMacroCallerLoc(Loc);
-
-  while (S.SourceMgr.isMacroArgExpansion(CC))
-CC = S.SourceMgr.getImmediateMacroCallerLoc(CC);
+  Loc = S.SourceMgr.getTopMacroCallerLoc(Loc);
+  CC = S.SourceMgr.getTopMacroCallerLoc(CC);
 
   // __null is usually wrapped in a macro.  Go up a macro if that is the case.
   if (NullKind == Expr::NPCK_GNUNull && Loc.isMacroID()) {
Index: lib/Edit/Commit.cpp
===
--- lib/Edit/Commit.cpp
+++ lib/Edit/Commit.cpp
@@ -225,8 +225,7 @@
 isAtStartOfMacroExpansion(loc, );
 
   const SourceManager  = SourceMgr;
-  while (SM.isMacroArgExpansion(loc))
-loc = SM.getImmediateSpellingLoc(loc);
+  loc = SM.getTopMacroCallerLoc(loc);
 
   if (loc.isMacroID())
 if (!isAtStartOfMacroExpansion(loc, ))
@@ -256,8 +255,7 @@
 isAtEndOfMacroExpansion(loc, );
 
   const SourceManager  = SourceMgr;
-  while (SM.isMacroArgExpansion(loc))
-loc = SM.getImmediateSpellingLoc(loc);
+  loc = SM.getTopMacroCallerLoc(loc);
 
   if (loc.isMacroID())
 if (!isAtEndOfMacroExpansion(loc, ))
Index: lib/Basic/SourceManager.cpp
===
--- lib/Basic/SourceManager.cpp
+++ lib/Basic/SourceManager.cpp
@@ -955,6 +955,12 @@
   return Expansion.getExpansionLocRange();
 }
 
+SourceLocation SourceManager::getTopMacroCallerLoc(SourceLocation Loc) const {
+  while (isMacroArgExpansion(Loc))
+Loc = getImmediateSpellingLoc(Loc);
+  return Loc;
+}
+
 /// getExpansionRange - Given a SourceLocation object, return the range of
 /// tokens covered by the expansion in the ultimate file.
 std::pair
Index: include/clang/Basic/SourceManager.h
===
--- include/clang/Basic/SourceManager.h
+++ include/clang/Basic/SourceManager.h
@@ -1646,6 +1646,9 @@
 return getImmediateExpansionRange(Loc).first;
   }
 
+  /// \return Location of the top-level macro caller.
+  SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const;
+
 private:
   friend class ASTReader;
   friend class ASTWriter;


Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -9357,11 +9357,8 @@
   // Venture through the macro stacks to get to the source of macro arguments.
   // The new location is a better location than the complete location that was
   // passed in.
-  while (S.SourceMgr.isMacroArgExpansion(Loc))
-Loc = S.SourceMgr.getImmediateMacroCallerLoc(Loc);
-
-  while (S.SourceMgr.isMacroArgExpansion(CC))
-CC = S.SourceMgr.getImmediateMacroCallerLoc(CC);
+  Loc = S.SourceMgr.getTopMacroCallerLoc(Loc);
+  CC = S.SourceMgr.getTopMacroCallerLoc(CC);
 
   // __null is usually wrapped in a macro.  Go up a macro if that is the case.
   if (NullKind == Expr::NPCK_GNUNull && Loc.isMacroID()) {
Index: lib/Edit/Commit.cpp
===
--- lib/Edit/Commit.cpp
+++ lib/Edit/Commit.cpp
@@ -225,8 +225,7 @@
 isAtStartOfMacroExpansion(loc, );
 
   const SourceManager  = SourceMgr;
-  while (SM.isMacroArgExpansion(loc))
-loc = SM.getImmediateSpellingLoc(loc);
+  loc = SM.getTopMacroCallerLoc(loc);
 
   if (loc.isMacroID())
 if (!isAtStartOfMacroExpansion(loc, ))
@@ -256,8 +255,7 @@
 isAtEndOfMacroExpansion(loc, );
 
   const SourceManager  = SourceMgr;
-  while (SM.isMacroArgExpansion(loc))
-loc = SM.getImmediateSpellingLoc(loc);
+  loc = SM.getTopMacroCallerLoc(loc);
 
   if (loc.isMacroID())
 if (!isAtEndOfMacroExpansion(loc, ))
Index: lib/Basic/SourceManager.cpp
===
--- lib/Basic/SourceManager.cpp
+++ lib/Basic/SourceManager.cpp
@@ -955,6 +955,12 @@
   return Expansion.getExpansionLocRange();
 }
 
+SourceLocation SourceManager::getTopMacroCallerLoc(SourceLocation Loc) const {
+  while (isMacroArgExpansion(Loc))
+Loc = getImmediateSpellingLoc(Loc);
+  return Loc;
+}
+
 /// getExpansionRange - Given a 

[PATCH] D42458: [NFC] Extract method to SourceManager for traversing the macro "stack"

2018-02-09 Thread George Karpenkov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL324780: [NFC] Extract method to SourceManager for traversing 
the macro stack (authored by george.karpenkov, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D42458?vs=131187=133704#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D42458

Files:
  cfe/trunk/include/clang/Basic/SourceManager.h
  cfe/trunk/lib/Basic/SourceManager.cpp
  cfe/trunk/lib/Edit/Commit.cpp
  cfe/trunk/lib/Sema/SemaChecking.cpp


Index: cfe/trunk/include/clang/Basic/SourceManager.h
===
--- cfe/trunk/include/clang/Basic/SourceManager.h
+++ cfe/trunk/include/clang/Basic/SourceManager.h
@@ -1646,6 +1646,9 @@
 return getImmediateExpansionRange(Loc).first;
   }
 
+  /// \return Location of the top-level macro caller.
+  SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const;
+
 private:
   friend class ASTReader;
   friend class ASTWriter;
Index: cfe/trunk/lib/Sema/SemaChecking.cpp
===
--- cfe/trunk/lib/Sema/SemaChecking.cpp
+++ cfe/trunk/lib/Sema/SemaChecking.cpp
@@ -9357,11 +9357,8 @@
   // Venture through the macro stacks to get to the source of macro arguments.
   // The new location is a better location than the complete location that was
   // passed in.
-  while (S.SourceMgr.isMacroArgExpansion(Loc))
-Loc = S.SourceMgr.getImmediateMacroCallerLoc(Loc);
-
-  while (S.SourceMgr.isMacroArgExpansion(CC))
-CC = S.SourceMgr.getImmediateMacroCallerLoc(CC);
+  Loc = S.SourceMgr.getTopMacroCallerLoc(Loc);
+  CC = S.SourceMgr.getTopMacroCallerLoc(CC);
 
   // __null is usually wrapped in a macro.  Go up a macro if that is the case.
   if (NullKind == Expr::NPCK_GNUNull && Loc.isMacroID()) {
Index: cfe/trunk/lib/Edit/Commit.cpp
===
--- cfe/trunk/lib/Edit/Commit.cpp
+++ cfe/trunk/lib/Edit/Commit.cpp
@@ -225,8 +225,7 @@
 isAtStartOfMacroExpansion(loc, );
 
   const SourceManager  = SourceMgr;
-  while (SM.isMacroArgExpansion(loc))
-loc = SM.getImmediateSpellingLoc(loc);
+  loc = SM.getTopMacroCallerLoc(loc);
 
   if (loc.isMacroID())
 if (!isAtStartOfMacroExpansion(loc, ))
@@ -256,8 +255,7 @@
 isAtEndOfMacroExpansion(loc, );
 
   const SourceManager  = SourceMgr;
-  while (SM.isMacroArgExpansion(loc))
-loc = SM.getImmediateSpellingLoc(loc);
+  loc = SM.getTopMacroCallerLoc(loc);
 
   if (loc.isMacroID())
 if (!isAtEndOfMacroExpansion(loc, ))
Index: cfe/trunk/lib/Basic/SourceManager.cpp
===
--- cfe/trunk/lib/Basic/SourceManager.cpp
+++ cfe/trunk/lib/Basic/SourceManager.cpp
@@ -955,6 +955,12 @@
   return Expansion.getExpansionLocRange();
 }
 
+SourceLocation SourceManager::getTopMacroCallerLoc(SourceLocation Loc) const {
+  while (isMacroArgExpansion(Loc))
+Loc = getImmediateSpellingLoc(Loc);
+  return Loc;
+}
+
 /// getExpansionRange - Given a SourceLocation object, return the range of
 /// tokens covered by the expansion in the ultimate file.
 std::pair


Index: cfe/trunk/include/clang/Basic/SourceManager.h
===
--- cfe/trunk/include/clang/Basic/SourceManager.h
+++ cfe/trunk/include/clang/Basic/SourceManager.h
@@ -1646,6 +1646,9 @@
 return getImmediateExpansionRange(Loc).first;
   }
 
+  /// \return Location of the top-level macro caller.
+  SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const;
+
 private:
   friend class ASTReader;
   friend class ASTWriter;
Index: cfe/trunk/lib/Sema/SemaChecking.cpp
===
--- cfe/trunk/lib/Sema/SemaChecking.cpp
+++ cfe/trunk/lib/Sema/SemaChecking.cpp
@@ -9357,11 +9357,8 @@
   // Venture through the macro stacks to get to the source of macro arguments.
   // The new location is a better location than the complete location that was
   // passed in.
-  while (S.SourceMgr.isMacroArgExpansion(Loc))
-Loc = S.SourceMgr.getImmediateMacroCallerLoc(Loc);
-
-  while (S.SourceMgr.isMacroArgExpansion(CC))
-CC = S.SourceMgr.getImmediateMacroCallerLoc(CC);
+  Loc = S.SourceMgr.getTopMacroCallerLoc(Loc);
+  CC = S.SourceMgr.getTopMacroCallerLoc(CC);
 
   // __null is usually wrapped in a macro.  Go up a macro if that is the case.
   if (NullKind == Expr::NPCK_GNUNull && Loc.isMacroID()) {
Index: cfe/trunk/lib/Edit/Commit.cpp
===
--- cfe/trunk/lib/Edit/Commit.cpp
+++ cfe/trunk/lib/Edit/Commit.cpp
@@ -225,8 +225,7 @@
 isAtStartOfMacroExpansion(loc, );
 
   const SourceManager  = SourceMgr;
-  while (SM.isMacroArgExpansion(loc))
-loc = SM.getImmediateSpellingLoc(loc);
+  loc = SM.getTopMacroCallerLoc(loc);
 
   if (loc.isMacroID())

r324780 - [NFC] Extract method to SourceManager for traversing the macro "stack"

2018-02-09 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Feb  9 15:30:07 2018
New Revision: 324780

URL: http://llvm.org/viewvc/llvm-project?rev=324780=rev
Log:
[NFC] Extract method to SourceManager for traversing the macro "stack"

The code for going up the macro arg expansion is duplicated in many
places (and we need it for the analyzer as well, so I did not want to
duplicate it two more times).

This patch is an NFC, so the semantics should remain the same.

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

Modified:
cfe/trunk/include/clang/Basic/SourceManager.h
cfe/trunk/lib/Basic/SourceManager.cpp
cfe/trunk/lib/Edit/Commit.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp

Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=324780=324779=324780=diff
==
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Fri Feb  9 15:30:07 2018
@@ -1646,6 +1646,9 @@ public:
 return getImmediateExpansionRange(Loc).first;
   }
 
+  /// \return Location of the top-level macro caller.
+  SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const;
+
 private:
   friend class ASTReader;
   friend class ASTWriter;

Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=324780=324779=324780=diff
==
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Fri Feb  9 15:30:07 2018
@@ -955,6 +955,12 @@ SourceManager::getImmediateExpansionRang
   return Expansion.getExpansionLocRange();
 }
 
+SourceLocation SourceManager::getTopMacroCallerLoc(SourceLocation Loc) const {
+  while (isMacroArgExpansion(Loc))
+Loc = getImmediateSpellingLoc(Loc);
+  return Loc;
+}
+
 /// getExpansionRange - Given a SourceLocation object, return the range of
 /// tokens covered by the expansion in the ultimate file.
 std::pair

Modified: cfe/trunk/lib/Edit/Commit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/Commit.cpp?rev=324780=324779=324780=diff
==
--- cfe/trunk/lib/Edit/Commit.cpp (original)
+++ cfe/trunk/lib/Edit/Commit.cpp Fri Feb  9 15:30:07 2018
@@ -225,8 +225,7 @@ bool Commit::canInsert(SourceLocation lo
 isAtStartOfMacroExpansion(loc, );
 
   const SourceManager  = SourceMgr;
-  while (SM.isMacroArgExpansion(loc))
-loc = SM.getImmediateSpellingLoc(loc);
+  loc = SM.getTopMacroCallerLoc(loc);
 
   if (loc.isMacroID())
 if (!isAtStartOfMacroExpansion(loc, ))
@@ -256,8 +255,7 @@ bool Commit::canInsertAfterToken(SourceL
 isAtEndOfMacroExpansion(loc, );
 
   const SourceManager  = SourceMgr;
-  while (SM.isMacroArgExpansion(loc))
-loc = SM.getImmediateSpellingLoc(loc);
+  loc = SM.getTopMacroCallerLoc(loc);
 
   if (loc.isMacroID())
 if (!isAtEndOfMacroExpansion(loc, ))

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=324780=324779=324780=diff
==
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Feb  9 15:30:07 2018
@@ -9357,11 +9357,8 @@ static void DiagnoseNullConversion(Sema
   // Venture through the macro stacks to get to the source of macro arguments.
   // The new location is a better location than the complete location that was
   // passed in.
-  while (S.SourceMgr.isMacroArgExpansion(Loc))
-Loc = S.SourceMgr.getImmediateMacroCallerLoc(Loc);
-
-  while (S.SourceMgr.isMacroArgExpansion(CC))
-CC = S.SourceMgr.getImmediateMacroCallerLoc(CC);
+  Loc = S.SourceMgr.getTopMacroCallerLoc(Loc);
+  CC = S.SourceMgr.getTopMacroCallerLoc(CC);
 
   // __null is usually wrapped in a macro.  Go up a macro if that is the case.
   if (NullKind == Expr::NPCK_GNUNull && Loc.isMacroID()) {


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


[PATCH] D43089: clang: Add ARCTargetInfo

2018-02-09 Thread Tatyana Krasnukha via Phabricator via cfe-commits
tatyana-krasnukha added a comment.

This is what I could note




Comment at: clang/lib/Basic/Targets/ARC.h:26
+class LLVM_LIBRARY_VISIBILITY ARCTargetInfo : public TargetInfo {
+  static const Builtin::Info BuiltinInfo[];
+

Looks like unused member, while getTargetBuiltins returns 'None'



Comment at: clang/lib/CodeGen/TargetInfo.cpp:8123
+public:
+  ARCABIInfo(CodeGen::CodeGenTypes ) : DefaultABIInfo(CGT) {}
+

Better use '= default' instead of {}
And you even may use inheriting constructor here



Comment at: clang/lib/CodeGen/TargetInfo.cpp:8165
+  ARCTargetCodeGenInfo(CodeGenTypes )
+  : TargetCodeGenInfo(new ARCABIInfo(CGT)) {}
+};

and here


https://reviews.llvm.org/D43089



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


[PATCH] D43144: [analyzer] Implement path notes for temporary destructors.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 133692.
NoQ added a comment.

Add  a test for returning from destructor.


https://reviews.llvm.org/D43144

Files:
  lib/StaticAnalyzer/Core/PathDiagnostic.cpp
  test/Analysis/inlining/temp-dtors-path-notes.cpp


Index: test/Analysis/inlining/temp-dtors-path-notes.cpp
===
--- /dev/null
+++ test/Analysis/inlining/temp-dtors-path-notes.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_analyze_cc1 -analyze -analyzer-checker core -analyzer-config 
cfg-temporary-dtors=true -analyzer-output=text -verify %s
+
+namespace test_simple_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // expected-note{{The value 0 is assigned to field 'x'}}
+  ~C() { x = 1 / x; } // expected-warning{{Division by zero}}
+  // expected-note@-1{{Division by zero}}
+};
+
+void test() {
+  C(0); // expected-note   {{Passing the value 0 via 1st parameter 'x'}}
+// expected-note@-1{{Calling constructor for 'C'}}
+// expected-note@-2{{Returning from constructor for 'C'}}
+// expected-note@-3{{Calling '~C'}}
+}
+} // end namespace test_simple_temporary
+
+namespace test_lifetime_extended_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // expected-note{{The value 0 is assigned to field 'x'}}
+  void nop() const {}
+  ~C() { x = 1 / x; } // expected-warning{{Division by zero}}
+  // expected-note@-1{{Division by zero}}
+};
+
+void test(int coin) {
+  // We'd divide by zero in the temporary destructor that goes after the
+  // elidable copy-constructor from C(0) to the lifetime-extended temporary.
+  // So in fact this example has nothing to do with lifetime extension.
+  // Actually, it would probably be better to elide the constructor, and
+  // put the note for the destructor call at the closing brace after nop.
+  const C  = coin ? C(1) : C(0); // expected-note   {{Assuming 'coin' is 0}}
+   // expected-note@-1{{'?' condition is 
false}}
+   // expected-note@-2{{Passing the value 0 
via 1st parameter 'x'}}
+   // expected-note@-3{{Calling constructor 
for 'C'}}
+   // expected-note@-4{{Returning from 
constructor for 'C'}}
+   // expected-note@-5{{Calling '~C'}}
+  c.nop();
+}
+} // end namespace test_lifetime_extended_temporary
+
+namespace test_bug_after_dtor {
+int glob;
+
+class C {
+public:
+  C() { glob += 1; }
+  ~C() { glob -= 2; } // expected-note{{The value 0 is assigned to 'glob'}}
+};
+
+void test() {
+  glob = 1;
+  C(); // expected-note   {{Calling '~C'}}
+   // expected-note@-1{{Returning from '~C'}}
+  glob = 1 / glob; // expected-warning{{Division by zero}}
+   // expected-note@-1{{Division by zero}}
+}
+} // end namespace test_bug_after_dtor
Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp
===
--- lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -579,8 +579,14 @@
 const CFGNewAllocator  = Source.castAs();
 return PathDiagnosticLocation(Alloc.getAllocatorExpr(), SM, CallerCtx);
   }
-  case CFGElement::TemporaryDtor:
-llvm_unreachable("not yet implemented!");
+  case CFGElement::TemporaryDtor: {
+// Temporary destructors are for temporaries. They die immediately at 
around
+// the location of CXXBindTemporaryExpr. If they are lifetime-extended,
+// they'd be dealt with via an AutomaticObjectDtor instead.
+const auto  = Source.castAs();
+return PathDiagnosticLocation::createEnd(Dtor.getBindTemporaryExpr(), SM,
+ CallerCtx);
+  }
   case CFGElement::LifetimeEnds:
   case CFGElement::LoopExit:
 llvm_unreachable("CFGElement kind should not be on callsite!");


Index: test/Analysis/inlining/temp-dtors-path-notes.cpp
===
--- /dev/null
+++ test/Analysis/inlining/temp-dtors-path-notes.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_analyze_cc1 -analyze -analyzer-checker core -analyzer-config cfg-temporary-dtors=true -analyzer-output=text -verify %s
+
+namespace test_simple_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // expected-note{{The value 0 is assigned to field 'x'}}
+  ~C() { x = 1 / x; } // expected-warning{{Division by zero}}
+  // expected-note@-1{{Division by zero}}
+};
+
+void test() {
+  C(0); // expected-note   {{Passing the value 0 via 1st parameter 'x'}}
+// expected-note@-1{{Calling constructor for 'C'}}
+// expected-note@-2{{Returning from constructor for 'C'}}
+// expected-note@-3{{Calling '~C'}}
+}
+} // end namespace test_simple_temporary
+
+namespace test_lifetime_extended_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // 

[PATCH] D43144: [analyzer] Implement path notes for temporary destructors.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

Another question is why do we have such inconsistency between `Calling 
constructor for 'C'` and `Calling '~C'`, i.e. why not `Calling destructor for 
'C'`. Seems accidental.


https://reviews.llvm.org/D43144



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


[PATCH] D43144: [analyzer] Implement path notes for temporary destructors.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added inline comments.



Comment at: test/Analysis/inlining/temp-dtors-path-notes.cpp:17
+// expected-note@-2{{Returning from constructor for 'C'}}
+// expected-note@-3{{Calling '~C'}}
+}

george.karpenkov wrote:
> Should we have "returning from ~C"? At least we do have it for inlined 
> functions.
Not here, because the bug occurs within `~C`. But we should definitely test it, 
yeah.


https://reviews.llvm.org/D43144



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


[PATCH] D43089: clang: Add ARCTargetInfo

2018-02-09 Thread Pete Couperus via Phabricator via cfe-commits
petecoup added a comment.

Hi Tatyana,

Thanks for checking against lldb! I will try and find a couple of people who 
can review this as a clang change.

Pete


https://reviews.llvm.org/D43089



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


[PATCH] D43144: [analyzer] Implement path notes for temporary destructors.

2018-02-09 Thread George Karpenkov via Phabricator via cfe-commits
george.karpenkov accepted this revision.
george.karpenkov added inline comments.
This revision is now accepted and ready to land.



Comment at: lib/StaticAnalyzer/Core/PathDiagnostic.cpp:586
+// they'd be dealt with via an AutomaticObjectDtor instead.
+const CFGTemporaryDtor  = Source.castAs();
+return PathDiagnosticLocation::createEnd(Dtor.getBindTemporaryExpr(), SM,

auto?



Comment at: test/Analysis/inlining/temp-dtors-path-notes.cpp:17
+// expected-note@-2{{Returning from constructor for 'C'}}
+// expected-note@-3{{Calling '~C'}}
+}

Should we have "returning from ~C"? At least we do have it for inlined 
functions.


https://reviews.llvm.org/D43144



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


[PATCH] D43089: clang: Add ARCTargetInfo

2018-02-09 Thread Tatyana Krasnukha via Phabricator via cfe-commits
tatyana-krasnukha added a comment.

Hello Pete,

Thank you for upstreaming ARC target to clang! I checked it in couple with lldb 
- works well. So, the revision is good to me. But it seems, I have no rights to 
accept revisions yet...


https://reviews.llvm.org/D43089



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


[PATCH] D43144: [analyzer] Implement path notes for temporary destructors.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 133687.
NoQ added a comment.

Minor indent fix.


https://reviews.llvm.org/D43144

Files:
  lib/StaticAnalyzer/Core/PathDiagnostic.cpp
  test/Analysis/inlining/temp-dtors-path-notes.cpp


Index: test/Analysis/inlining/temp-dtors-path-notes.cpp
===
--- /dev/null
+++ test/Analysis/inlining/temp-dtors-path-notes.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_analyze_cc1 -analyze -analyzer-checker core -analyzer-config 
cfg-temporary-dtors=true -analyzer-output=text -verify %s
+
+namespace test_simple_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // expected-note{{The value 0 is assigned to field 'x'}}
+  ~C() { x = 1 / x; } // expected-warning{{Division by zero}}
+  // expected-note@-1{{Division by zero}}
+};
+
+void test() {
+  C(0); // expected-note   {{Passing the value 0 via 1st parameter 'x'}}
+// expected-note@-1{{Calling constructor for 'C'}}
+// expected-note@-2{{Returning from constructor for 'C'}}
+// expected-note@-3{{Calling '~C'}}
+}
+} // end namespace test_simple_temporary
+
+namespace test_lifetime_extended_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // expected-note{{The value 0 is assigned to field 'x'}}
+  void nop() const {}
+  ~C() { x = 1 / x; } // expected-warning{{Division by zero}}
+  // expected-note@-1{{Division by zero}}
+};
+
+void test(int coin) {
+  // We'd divide by zero in the temporary destructor that goes after the
+  // elidable copy-constructor from C(0) to the lifetime-extended temporary.
+  // So in fact this example has nothing to do with lifetime extension.
+  // Actually, it would probably be better to elide the constructor, and
+  // put the note for the destructor call at the closing brace after nop.
+  const C  = coin ? C(1) : C(0); // expected-note   {{Assuming 'coin' is 0}}
+   // expected-note@-1{{'?' condition is 
false}}
+   // expected-note@-2{{Passing the value 0 
via 1st parameter 'x'}}
+   // expected-note@-3{{Calling constructor 
for 'C'}}
+   // expected-note@-4{{Returning from 
constructor for 'C'}}
+   // expected-note@-5{{Calling '~C'}}
+  c.nop();
+}
+} // end namespace test_lifetime_extended_temporary
Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp
===
--- lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -579,8 +579,14 @@
 const CFGNewAllocator  = Source.castAs();
 return PathDiagnosticLocation(Alloc.getAllocatorExpr(), SM, CallerCtx);
   }
-  case CFGElement::TemporaryDtor:
-llvm_unreachable("not yet implemented!");
+  case CFGElement::TemporaryDtor: {
+// Temporary destructors are for temporaries. They die immediately at 
around
+// the location of CXXBindTemporaryExpr. If they are lifetime-extended,
+// they'd be dealt with via an AutomaticObjectDtor instead.
+const CFGTemporaryDtor  = Source.castAs();
+return PathDiagnosticLocation::createEnd(Dtor.getBindTemporaryExpr(), SM,
+ CallerCtx);
+  }
   case CFGElement::LifetimeEnds:
   case CFGElement::LoopExit:
 llvm_unreachable("CFGElement kind should not be on callsite!");


Index: test/Analysis/inlining/temp-dtors-path-notes.cpp
===
--- /dev/null
+++ test/Analysis/inlining/temp-dtors-path-notes.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_analyze_cc1 -analyze -analyzer-checker core -analyzer-config cfg-temporary-dtors=true -analyzer-output=text -verify %s
+
+namespace test_simple_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // expected-note{{The value 0 is assigned to field 'x'}}
+  ~C() { x = 1 / x; } // expected-warning{{Division by zero}}
+  // expected-note@-1{{Division by zero}}
+};
+
+void test() {
+  C(0); // expected-note   {{Passing the value 0 via 1st parameter 'x'}}
+// expected-note@-1{{Calling constructor for 'C'}}
+// expected-note@-2{{Returning from constructor for 'C'}}
+// expected-note@-3{{Calling '~C'}}
+}
+} // end namespace test_simple_temporary
+
+namespace test_lifetime_extended_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // expected-note{{The value 0 is assigned to field 'x'}}
+  void nop() const {}
+  ~C() { x = 1 / x; } // expected-warning{{Division by zero}}
+  // expected-note@-1{{Division by zero}}
+};
+
+void test(int coin) {
+  // We'd divide by zero in the temporary destructor that goes after the
+  // elidable copy-constructor from C(0) to the lifetime-extended temporary.
+  // So in fact this example has nothing to do with lifetime extension.
+  // Actually, it would 

[PATCH] D43144: [analyzer] Implement path notes for temporary destructors.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet.
Herald added subscribers: cfe-commits, rnkovacs.

Temporaries are destroyed at the end of their `CXXBindTemporaryExpr`, which can 
be picked up from their `CFGTemporaryDtor`. Note that lifetime-extended 
temporaries are different: they are destroyed via `CFGAutomaticObjectDtor` for 
their reference, and they don't have a `CFGTemoraryDtor` of their own. Unless, 
well, they are copied with an elidable copy-constructor, in which case the 
temporary destructor is there, but it still fires immediately, and 
lifetime-extended copy is still dealt with via an automatic destructor.

I think this is one of the places where diagnostics may become confusing due to 
presence of elidable constructors and their respective destructors. In the 
second test case nobody would expect anything to be destroyed on the line on 
which we show the "Calling '~C'" note. So we may need to either think of 
actually eliding elidable constructors together with their destructors, or at 
least explaining to the user that the constructor is elidable as part of the 
path note.


Repository:
  rC Clang

https://reviews.llvm.org/D43144

Files:
  lib/StaticAnalyzer/Core/PathDiagnostic.cpp
  test/Analysis/inlining/temp-dtors-path-notes.cpp


Index: test/Analysis/inlining/temp-dtors-path-notes.cpp
===
--- /dev/null
+++ test/Analysis/inlining/temp-dtors-path-notes.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_analyze_cc1 -analyze -analyzer-checker core -analyzer-config 
cfg-temporary-dtors=true -analyzer-output=text -verify %s
+
+namespace test_simple_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // expected-note{{The value 0 is assigned to field 'x'}}
+  ~C() { x = 1 / x; } // expected-warning{{Division by zero}}
+  // expected-note@-1{{Division by zero}}
+};
+
+void test() {
+  C(0); // expected-note   {{Passing the value 0 via 1st parameter 'x'}}
+// expected-note@-1{{Calling constructor for 'C'}}
+// expected-note@-2{{Returning from constructor for 'C'}}
+// expected-note@-3{{Calling '~C'}}
+}
+} // end namespace test_simple_temporary
+
+namespace test_lifetime_extended_temporary {
+class C {
+  int x;
+
+public:
+  C(int x): x(x) {} // expected-note{{The value 0 is assigned to field 'x'}}
+  void nop() const {}
+  ~C() { x = 1 / x; } // expected-warning{{Division by zero}}
+  // expected-note@-1{{Division by zero}}
+};
+
+void test(int coin) {
+  // We'd divide by zero in the temporary destructor that goes after the
+  // elidable copy-constructor from C(0) to the lifetime-extended temporary.
+  // So in fact this example has nothing to do with lifetime extension.
+  // Actually, it would probably be better to elide the constructor, and
+  // put the note for the destructor call at the closing brace after nop.
+  const C  = coin ? C(1) : C(0); // expected-note{{Assuming 'coin' is 0}}
+   // expected-note@-1{{'?' condition is 
false}}
+   // expected-note@-2{{Passing the value 0 
via 1st parameter 'x'}}
+   // expected-note@-3{{Calling constructor 
for 'C'}}
+   // expected-note@-4{{Returning from 
constructor for 'C'}}
+   // expected-note@-5{{Calling '~C'}}
+  c.nop();
+}
+} // end namespace test_lifetime_extended_temporary
Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp
===
--- lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -579,8 +579,14 @@
 const CFGNewAllocator  = Source.castAs();
 return PathDiagnosticLocation(Alloc.getAllocatorExpr(), SM, CallerCtx);
   }
-  case CFGElement::TemporaryDtor:
-llvm_unreachable("not yet implemented!");
+  case CFGElement::TemporaryDtor: {
+// Temporary destructors are for temporaries. They die immediately at 
around
+// the location of CXXBindTemporaryExpr. If they are lifetime-extended,
+// they'd be dealt with via an AutomaticObjectDtor instead.
+const CFGTemporaryDtor  = Source.castAs();
+return PathDiagnosticLocation::createEnd(Dtor.getBindTemporaryExpr(), SM,
+ CallerCtx);
+  }
   case CFGElement::LifetimeEnds:
   case CFGElement::LoopExit:
 llvm_unreachable("CFGElement kind should not be on callsite!");


Index: test/Analysis/inlining/temp-dtors-path-notes.cpp
===
--- /dev/null
+++ test/Analysis/inlining/temp-dtors-path-notes.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_analyze_cc1 -analyze -analyzer-checker core -analyzer-config cfg-temporary-dtors=true -analyzer-output=text -verify %s
+
+namespace test_simple_temporary {
+class C {
+  int x;
+
+public:
+  

[PATCH] D42549: [CodeGen] Use the zero initializer instead of storing an all zero representation.

2018-02-09 Thread Matt Davis via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC324776: [CodeGen] Use the zero initializer instead of 
storing an all zero… (authored by mattd, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D42549

Files:
  lib/CodeGen/CGExprConstant.cpp
  test/CodeGen/array-init.c


Index: test/CodeGen/array-init.c
===
--- test/CodeGen/array-init.c
+++ test/CodeGen/array-init.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -O0 -triple x86_64-unknown-linux-gnu -emit-llvm -o - | 
FileCheck %s
+
+// CHECK: @{{.*}}.a1 = internal constant [5 x i32] [i32 0, i32 1, i32 2, i32 
0, i32 0]
+// CHECK: @{{.*}}.a2 = internal constant [5 x i32] zeroinitializer
+// CHECK: @{{.*}}.a3 = internal constant [5 x i32] zeroinitializer
+
+void testConstArrayInits(void)
+{
+  const int a1[5] = {0,1,2};
+  const int a2[5] = {0,0,0};
+  const int a3[5] = {0};
+}
Index: lib/CodeGen/CGExprConstant.cpp
===
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -859,25 +859,33 @@
 
 // Copy initializer elements.
 SmallVector Elts;
-Elts.reserve(NumInitableElts + NumElements);
+Elts.reserve(std::max(NumInitableElts, NumElements));
 
 bool RewriteType = false;
+bool AllNullValues = true;
 for (unsigned i = 0; i < NumInitableElts; ++i) {
   Expr *Init = ILE->getInit(i);
   llvm::Constant *C = Emitter.tryEmitPrivateForMemory(Init, EltType);
   if (!C)
 return nullptr;
   RewriteType |= (C->getType() != ElemTy);
   Elts.push_back(C);
+  if (AllNullValues && !C->isNullValue())
+AllNullValues = false;
 }
 
+// If all initializer elements are "zero," then avoid storing NumElements
+// instances of the zero representation.
+if (AllNullValues)
+  return llvm::ConstantAggregateZero::get(AType);
+
 RewriteType |= (fillC->getType() != ElemTy);
 Elts.resize(NumElements, fillC);
 
 if (RewriteType) {
   // FIXME: Try to avoid packing the array
   std::vector Types;
-  Types.reserve(NumInitableElts + NumElements);
+  Types.reserve(Elts.size());
   for (unsigned i = 0, e = Elts.size(); i < e; ++i)
 Types.push_back(Elts[i]->getType());
   llvm::StructType *SType = llvm::StructType::get(AType->getContext(),


Index: test/CodeGen/array-init.c
===
--- test/CodeGen/array-init.c
+++ test/CodeGen/array-init.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -O0 -triple x86_64-unknown-linux-gnu -emit-llvm -o - | FileCheck %s
+
+// CHECK: @{{.*}}.a1 = internal constant [5 x i32] [i32 0, i32 1, i32 2, i32 0, i32 0]
+// CHECK: @{{.*}}.a2 = internal constant [5 x i32] zeroinitializer
+// CHECK: @{{.*}}.a3 = internal constant [5 x i32] zeroinitializer
+
+void testConstArrayInits(void)
+{
+  const int a1[5] = {0,1,2};
+  const int a2[5] = {0,0,0};
+  const int a3[5] = {0};
+}
Index: lib/CodeGen/CGExprConstant.cpp
===
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -859,25 +859,33 @@
 
 // Copy initializer elements.
 SmallVector Elts;
-Elts.reserve(NumInitableElts + NumElements);
+Elts.reserve(std::max(NumInitableElts, NumElements));
 
 bool RewriteType = false;
+bool AllNullValues = true;
 for (unsigned i = 0; i < NumInitableElts; ++i) {
   Expr *Init = ILE->getInit(i);
   llvm::Constant *C = Emitter.tryEmitPrivateForMemory(Init, EltType);
   if (!C)
 return nullptr;
   RewriteType |= (C->getType() != ElemTy);
   Elts.push_back(C);
+  if (AllNullValues && !C->isNullValue())
+AllNullValues = false;
 }
 
+// If all initializer elements are "zero," then avoid storing NumElements
+// instances of the zero representation.
+if (AllNullValues)
+  return llvm::ConstantAggregateZero::get(AType);
+
 RewriteType |= (fillC->getType() != ElemTy);
 Elts.resize(NumElements, fillC);
 
 if (RewriteType) {
   // FIXME: Try to avoid packing the array
   std::vector Types;
-  Types.reserve(NumInitableElts + NumElements);
+  Types.reserve(Elts.size());
   for (unsigned i = 0, e = Elts.size(); i < e; ++i)
 Types.push_back(Elts[i]->getType());
   llvm::StructType *SType = llvm::StructType::get(AType->getContext(),
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r324776 - [CodeGen] Use the zero initializer instead of storing an all zero representation.

2018-02-09 Thread Matt Davis via cfe-commits
Author: mattd
Date: Fri Feb  9 14:10:09 2018
New Revision: 324776

URL: http://llvm.org/viewvc/llvm-project?rev=324776=rev
Log:
[CodeGen] Use the zero initializer instead of storing an all zero 
representation.

Summary:
This change avoids the overhead of storing, and later crawling,
an initializer list of all zeros for arrays. When LLVM
visits this (llvm/IR/Constants.cpp) ConstantArray::getImpl()
it will scan the list looking for an array of all zero.

We can avoid the store, and short-cut the scan, by detecting
all zeros when clang builds-up the initialization representation.

This was brought to my attention when investigating PR36030


Reviewers: majnemer, rjmccall

Reviewed By: rjmccall

Subscribers: cfe-commits

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

Added:
cfe/trunk/test/CodeGen/array-init.c
Modified:
cfe/trunk/lib/CodeGen/CGExprConstant.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=324776=324775=324776=diff
==
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Fri Feb  9 14:10:09 2018
@@ -859,9 +859,10 @@ public:
 
 // Copy initializer elements.
 SmallVector Elts;
-Elts.reserve(NumInitableElts + NumElements);
+Elts.reserve(std::max(NumInitableElts, NumElements));
 
 bool RewriteType = false;
+bool AllNullValues = true;
 for (unsigned i = 0; i < NumInitableElts; ++i) {
   Expr *Init = ILE->getInit(i);
   llvm::Constant *C = Emitter.tryEmitPrivateForMemory(Init, EltType);
@@ -869,15 +870,22 @@ public:
 return nullptr;
   RewriteType |= (C->getType() != ElemTy);
   Elts.push_back(C);
+  if (AllNullValues && !C->isNullValue())
+AllNullValues = false;
 }
 
+// If all initializer elements are "zero," then avoid storing NumElements
+// instances of the zero representation.
+if (AllNullValues)
+  return llvm::ConstantAggregateZero::get(AType);
+
 RewriteType |= (fillC->getType() != ElemTy);
 Elts.resize(NumElements, fillC);
 
 if (RewriteType) {
   // FIXME: Try to avoid packing the array
   std::vector Types;
-  Types.reserve(NumInitableElts + NumElements);
+  Types.reserve(Elts.size());
   for (unsigned i = 0, e = Elts.size(); i < e; ++i)
 Types.push_back(Elts[i]->getType());
   llvm::StructType *SType = llvm::StructType::get(AType->getContext(),

Added: cfe/trunk/test/CodeGen/array-init.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/array-init.c?rev=324776=auto
==
--- cfe/trunk/test/CodeGen/array-init.c (added)
+++ cfe/trunk/test/CodeGen/array-init.c Fri Feb  9 14:10:09 2018
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -O0 -triple x86_64-unknown-linux-gnu -emit-llvm -o - | 
FileCheck %s
+
+// CHECK: @{{.*}}.a1 = internal constant [5 x i32] [i32 0, i32 1, i32 2, i32 
0, i32 0]
+// CHECK: @{{.*}}.a2 = internal constant [5 x i32] zeroinitializer
+// CHECK: @{{.*}}.a3 = internal constant [5 x i32] zeroinitializer
+
+void testConstArrayInits(void)
+{
+  const int a1[5] = {0,1,2};
+  const int a2[5] = {0,0,0};
+  const int a3[5] = {0};
+}


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


[PATCH] D42779: [analyzer] NFC: Make sure we don't ever inline the constructor for which the temporary destructor is noreturn and missing.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 133675.
NoQ marked an inline comment as done.
NoQ added a comment.

Add the comment.


https://reviews.llvm.org/D42779

Files:
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp


Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -350,20 +350,30 @@
   // paths when no-return temporary destructors are used for assertions.
   const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
   if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
-  const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
-  if (Target && isa(Target) &&
-  Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
+if (Target && isa(Target) &&
+Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+
+  // If we've inlined the constructor, then DstEvaluated would be empty.
+  // In this case we still want a sink, which could be implemented
+  // in processCallExit. But we don't have that implemented at the moment,
+  // so if you hit this assertion, see if you can avoid inlining
+  // the respective constructor when analyzer-config cfg-temporary-dtors
+  // is set to false.
+  // Otherwise there's nothing wrong with inlining such constructor.
+  assert(!DstEvaluated.empty() &&
+ "We should not have inlined this constructor!");
 
   for (ExplodedNode *N : DstEvaluated) {
 Bldr.generateSink(CE, N, N->getState());
   }
 
-  // There is no need to run the PostCall and PostStmtchecker
+  // There is no need to run the PostCall and PostStmt checker
   // callbacks because we just generated sinks on all nodes in th
   // frontier.
   return;
 }
- }
+  }
 
   ExplodedNodeSet DstPostCall;
   getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,


Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -350,20 +350,30 @@
   // paths when no-return temporary destructors are used for assertions.
   const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
   if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
-  const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
-  if (Target && isa(Target) &&
-  Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
+if (Target && isa(Target) &&
+Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
+
+  // If we've inlined the constructor, then DstEvaluated would be empty.
+  // In this case we still want a sink, which could be implemented
+  // in processCallExit. But we don't have that implemented at the moment,
+  // so if you hit this assertion, see if you can avoid inlining
+  // the respective constructor when analyzer-config cfg-temporary-dtors
+  // is set to false.
+  // Otherwise there's nothing wrong with inlining such constructor.
+  assert(!DstEvaluated.empty() &&
+ "We should not have inlined this constructor!");
 
   for (ExplodedNode *N : DstEvaluated) {
 Bldr.generateSink(CE, N, N->getState());
   }
 
-  // There is no need to run the PostCall and PostStmtchecker
+  // There is no need to run the PostCall and PostStmt checker
   // callbacks because we just generated sinks on all nodes in th
   // frontier.
   return;
 }
- }
+  }
 
   ExplodedNodeSet DstPostCall;
   getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43089: clang: Add ARCTargetInfo

2018-02-09 Thread Pete Couperus via Phabricator via cfe-commits
petecoup updated this revision to Diff 133674.
petecoup added a comment.

Hello Eugene,

Thanks for taking a look.
Changed // End anonymous namespace. -> // namespace


https://reviews.llvm.org/D43089

Files:
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/ARC.cpp
  clang/lib/Basic/Targets/ARC.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/arc-arguments.c
  clang/test/CodeGen/arc-struct-align.c
  clang/test/CodeGen/target-data.c

Index: clang/test/CodeGen/target-data.c
===
--- clang/test/CodeGen/target-data.c
+++ clang/test/CodeGen/target-data.c
@@ -159,6 +159,10 @@
 // RUN: %s | FileCheck %s -check-prefix=ARM-GNU
 // ARM-GNU: target datalayout = "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
 
+// RUN: %clang_cc1 -triple arc-unknown-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=ARC
+// ARC: target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32"
+
 // RUN: %clang_cc1 -triple hexagon-unknown -o - -emit-llvm %s | \
 // RUN: FileCheck %s -check-prefix=HEXAGON
 // HEXAGON: target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
Index: clang/test/CodeGen/arc-struct-align.c
===
--- /dev/null
+++ clang/test/CodeGen/arc-struct-align.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+// 64-bit fields need only be 32-bit aligned for arc.
+
+typedef struct {
+  int aa;
+  double bb;
+} s1;
+
+// CHECK: define i32 @f1
+// CHECK: ret i32 12
+int f1() {
+  return sizeof(s1);
+}
+
+typedef struct {
+  int aa;
+  long long bb;
+} s2;
+// CHECK: define i32 @f2
+// CHECK: ret i32 12
+int f2() {
+  return sizeof(s2);
+}
+
Index: clang/test/CodeGen/arc-arguments.c
===
--- /dev/null
+++ clang/test/CodeGen/arc-arguments.c
@@ -0,0 +1,135 @@
+// RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+// Basic argument tests for ARC.
+
+// CHECK: define void @f0(i32 %i, i32 %j, i64 %k)
+void f0(int i, long j, long long k) {}
+
+typedef struct {
+  int aa;
+  int bb;
+} s1;
+// CHECK: define void @f1(i32 %i.coerce0, i32 %i.coerce1)
+void f1(s1 i) {}
+
+typedef struct {
+  char aa; char bb; char cc; char dd;
+} cs1;
+// CHECK: define void @cf1(i32 %i.coerce)
+void cf1(cs1 i) {}
+
+typedef struct {
+  int cc;
+} s2;
+// CHECK: define void @f2(%struct.s2* noalias sret %agg.result)
+s2 f2() {
+  s2 foo;
+  return foo;
+}
+
+typedef struct {
+  int cc;
+  int dd;
+} s3;
+// CHECK: define void @f3(%struct.s3* noalias sret %agg.result)
+s3 f3() {
+  s3 foo;
+  return foo;
+}
+
+// CHECK: define void @f4(i64 %i)
+void f4(long long i) {}
+
+// CHECK: define void @f5(i8 signext %a, i16 signext %b)
+void f5(signed char a, short b) {}
+
+// CHECK: define void @f6(i8 zeroext %a, i16 zeroext %b)
+void f6(unsigned char a, unsigned short b) {}
+
+enum my_enum {
+  ENUM1,
+  ENUM2,
+  ENUM3,
+};
+// Enums should be treated as the underlying i32.
+// CHECK: define void @f7(i32 %a)
+void f7(enum my_enum a) {}
+
+enum my_big_enum {
+  ENUM4 = 0x,
+};
+// Big enums should be treated as the underlying i64.
+// CHECK: define void @f8(i64 %a)
+void f8(enum my_big_enum a) {}
+
+union simple_union {
+  int a;
+  char b;
+};
+// Unions should be passed inreg.
+// CHECK: define void @f9(i32 %s.coerce)
+void f9(union simple_union s) {}
+
+typedef struct {
+  int b4 : 4;
+  int b3 : 3;
+  int b8 : 8;
+} bitfield1;
+// Bitfields should be passed inreg.
+// CHECK: define void @f10(i32 %bf1.coerce)
+void f10(bitfield1 bf1) {}
+
+// CHECK: define { float, float } @cplx1(float %r)
+_Complex float cplx1(float r) {
+  return r + 2.0fi;
+}
+
+// CHECK: define { double, double } @cplx2(double %r)
+_Complex double cplx2(double r) {
+  return r + 2.0i;
+}
+
+// CHECK: define { i32, i32 } @cplx3(i32 %r)
+_Complex int cplx3(int r) {
+  return r + 2i;
+}
+
+// CHECK: define { i64, i64 } @cplx4(i64 %r)
+_Complex long long cplx4(long long r) {
+  return r + 2i;
+}
+
+// CHECK: define { i8, i8 } @cplx6(i8 signext %r)
+_Complex signed char cplx6(signed char r) {
+  return r + 2i;
+}
+
+// CHECK: define { i16, i16 } @cplx7(i16 signext %r)
+_Complex short cplx7(short r) {
+  return r + 2i;
+}
+
+typedef struct {
+  int aa; int bb;
+} s8;
+
+typedef struct {
+  int aa; int bb; int cc; int dd;
+} s16;
+
+// Use 16-byte struct 2 times, gets 8 registers.
+void st2(s16 a, s16 b) {}
+// CHECK: define void @st2(i32 %a.coerce0, i32 %a.coerce1, i32 %a.coerce2, i32 %a.coerce3, i32 %b.coerce0, i32 %b.coerce1, i32 %b.coerce2, i32 %b.coerce3)
+
+// Use 8-byte struct 3 times, gets 8 registers, 1 byval struct argument.
+void st3(s16 a, 

[PATCH] D43104: [analyzer] Find correct region for simple temporary destructor calls and inline them if possible.

2018-02-09 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 133672.
NoQ marked an inline comment as done.
NoQ added a comment.

Assert that the destructors are cleaned up. This assertion is pretty important 
because it says that we didn't miss any destructors for initialized temporaries 
during analysis.

Disable tracking initialized temporaries when `cfg-temporary-dtors` is off - a 
bug i introduced when moving the code, which was found by the newly added 
assertion :)


https://reviews.llvm.org/D43104

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
  lib/StaticAnalyzer/Core/CallEvent.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
  test/Analysis/temporaries.cpp

Index: test/Analysis/temporaries.cpp
===
--- test/Analysis/temporaries.cpp
+++ test/Analysis/temporaries.cpp
@@ -779,3 +779,81 @@
 }
 
 } // namespace test_temporary_object_expr
+
+namespace test_match_constructors_and_destructors {
+class C {
+public:
+  int , 
+  C(int &_x, int &_y) : x(_x), y(_y) { ++x; }
+  C(const C ): x(c.x), y(c.y) { ++x; }
+  ~C() { ++y; }
+};
+
+void test_simple_temporary() {
+  int x = 0, y = 0;
+  {
+const C  = C(x, y);
+  }
+  // One constructor and one destructor.
+  clang_analyzer_eval(x == 1);
+  clang_analyzer_eval(y == 1);
+#ifdef TEMPORARY_DTORS
+  // expected-warning@-3{{TRUE}}
+  // expected-warning@-3{{TRUE}}
+#else
+  // expected-warning@-6{{UNKNOWN}}
+  // expected-warning@-6{{UNKNOWN}}
+#endif
+}
+
+void test_simple_temporary_with_copy() {
+  int x = 0, y = 0;
+  {
+C c = C(x, y);
+  }
+  // Two constructors (temporary object expr and copy) and two destructors.
+  clang_analyzer_eval(x == 2);
+  clang_analyzer_eval(y == 2);
+#ifdef TEMPORARY_DTORS
+  // expected-warning@-3{{TRUE}}
+  // expected-warning@-3{{TRUE}}
+#else
+  // expected-warning@-6{{UNKNOWN}}
+  // expected-warning@-6{{UNKNOWN}}
+#endif
+}
+
+void test_ternary_temporary(int coin) {
+  int x = 0, y = 0, z = 0, w = 0;
+  {
+C c = coin ? C(x, y) : C(z, w);
+  }
+  // This time each branch contains an additional elidable copy constructor.
+  if (coin) {
+clang_analyzer_eval(x == 3);
+clang_analyzer_eval(y == 3);
+#ifdef TEMPORARY_DTORS
+// expected-warning@-3{{TRUE}}
+// expected-warning@-3{{TRUE}}
+#else
+// expected-warning@-6{{UNKNOWN}}
+// expected-warning@-6{{UNKNOWN}}
+#endif
+clang_analyzer_eval(z == 0); // expected-warning{{TRUE}}
+clang_analyzer_eval(w == 0); // expected-warning{{TRUE}}
+
+  } else {
+clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
+clang_analyzer_eval(y == 0); // expected-warning{{TRUE}}
+clang_analyzer_eval(z == 3);
+clang_analyzer_eval(w == 3);
+#ifdef TEMPORARY_DTORS
+// expected-warning@-3{{TRUE}}
+// expected-warning@-3{{TRUE}}
+#else
+// expected-warning@-6{{UNKNOWN}}
+// expected-warning@-6{{UNKNOWN}}
+#endif
+  }
+}
+} // namespace test_match_constructors_and_destructors
Index: lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -332,6 +332,7 @@
 
 // See if we have any stale C++ allocator values.
 assert(areCXXNewAllocatorValuesClear(CEEState, calleeCtx, callerCtx));
+assert(areInitializedTemporariesClear(CEEState, calleeCtx, callerCtx));
 
 ExplodedNode *CEENode = G.getNode(Loc, CEEState, false, );
 CEENode->addPredecessor(*I, G);
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -102,14 +102,15 @@
 const MemRegion *
 ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE,
   ExplodedNode *Pred,
+  const ConstructionContext *CC,
   EvalCallOptions ) {
   const LocationContext *LCtx = Pred->getLocationContext();
   ProgramStateRef State = Pred->getState();
   MemRegionManager  = getSValBuilder().getRegionManager();
 
   // See if we're constructing an existing region by looking at the
   // current construction context.
-  if (auto CC = getCurrentCFGElement().getAs()) {
+  if (CC) {
 if (const Stmt *TriggerStmt = CC->getTriggerStmt()) {
   if (const CXXNewExpr *CNE = dyn_cast(TriggerStmt)) {
 if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
@@ -217,10 +218,20 @@
   // the entire array).
 
   EvalCallOptions CallOpts;
+  auto C = getCurrentCFGElement().getAs();
+  const ConstructionContext *CC = C ? C->getConstructionContext() : nullptr;
+
+  const CXXBindTemporaryExpr *BTE = nullptr;
 
   switch (CE->getConstructionKind()) {
   case 

[PATCH] D43110: [Sema] Don't mark plain MS enums as fixed

2018-02-09 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

In https://reviews.llvm.org/D43110#1003171, @thakis wrote:

> Nice!
>
> Test?


Yeah, I forgot to get that in. From the test you can see that we have weirdly 
different behavior in C and C++ mode. Do people care? This is pre-existing 
behavior. My change makes the enum "unfixed" in C++, which changes the C++ 
behavior. Changing C mode to match C++ mode seems like it should be a separate 
change. Do people think we should do that as well?


https://reviews.llvm.org/D43110



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


[PATCH] D43110: [Sema] Don't mark plain MS enums as fixed

2018-02-09 Thread Reid Kleckner via Phabricator via cfe-commits
rnk updated this revision to Diff 133670.
rnk added a comment.

- Add test, update comments


https://reviews.llvm.org/D43110

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Type.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/Sema/sign-compare-enum.c

Index: clang/test/Sema/sign-compare-enum.c
===
--- clang/test/Sema/sign-compare-enum.c
+++ clang/test/Sema/sign-compare-enum.c
@@ -1,24 +1,77 @@
-// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify -Wsign-compare %s
-// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify -Wsign-compare %s
-// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -verify %s
-// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -Wsign-compare %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -verify -Wsign-compare %s
+// RUN: %clang_cc1 -x c++ -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -Wsign-compare %s
+// RUN: %clang_cc1 -x c++ -triple=x86_64-pc-win32 -fsyntax-only -verify -Wsign-compare %s
 
-int main() {
-  enum A { A_a = 0, A_b = 1 };
-  static const int message[] = {0, 1};
-  enum A a;
+// Check that -Wsign-compare is off by default.
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -DSILENCE %s
 
+#ifdef SILENCE
+// expected-no-diagnostics
+#endif
+
+enum PosEnum {
+  A_a = 0,
+  A_b = 1,
+  A_c = 10
+};
+
+static const int message[] = {0, 1};
+
+int test_pos(enum PosEnum a) {
   if (a < 2)
 return 0;
 
-#if defined(SIGNED) && !defined(SILENCE)
-  if (a < sizeof(message)/sizeof(message[0])) // expected-warning {{comparison of integers of different signs: 'enum A' and 'unsigned long long'}}
-return 0;
-#else
-  // expected-no-diagnostics
+  // No warning, except in Windows C mode, where PosEnum is 'int' and it can
+  // take on any value according to the C standard.
+#if !defined(SILENCE) && defined(_WIN32) && !defined(__cplusplus)
+  // expected-warning@+2 {{comparison of integers of different signs}}
+#endif
   if (a < 2U)
 return 0;
+
+  unsigned uv = 2;
+#if !defined(SILENCE) && defined(_WIN32) && !defined(__cplusplus)
+  // expected-warning@+2 {{comparison of integers of different signs}}
+#endif
+  if (a < uv)
+return 1;
+
+#if !defined(SILENCE) && defined(_WIN32) && !defined(__cplusplus)
+  // expected-warning@+2 {{comparison of integers of different signs}}
+#endif
   if (a < sizeof(message)/sizeof(message[0]))
 return 0;
+  return 4;
+}
+
+enum NegEnum {
+  NE_a = -1,
+  NE_b = 0,
+  NE_c = 10
+};
+
+int test_neg(enum NegEnum a) {
+  if (a < 2)
+return 0;
+
+#ifndef SILENCE
+  // expected-warning@+2 {{comparison of integers of different signs}}
+#endif
+  if (a < 2U)
+return 0;
+
+  unsigned uv = 2;
+#ifndef SILENCE
+  // expected-warning@+2 {{comparison of integers of different signs}}
+#endif
+  if (a < uv)
+return 1;
+
+#ifndef SILENCE
+  // expected-warning@+2 {{comparison of integers of different signs}}
 #endif
+  if (a < sizeof(message)/sizeof(message[0]))
+return 0;
+  return 4;
 }
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1040,8 +1040,7 @@
 SemaRef.SubstType(TI->getType(), TemplateArgs,
   UnderlyingLoc, DeclarationName());
   SemaRef.CheckEnumRedeclaration(Def->getLocation(), Def->isScoped(),
- DefnUnderlying,
- /*EnumUnderlyingIsImplicit=*/false, Enum);
+ DefnUnderlying, /*IsFixed=*/true, Enum);
 }
   }
 
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13236,11 +13236,9 @@
 
 /// Check whether this is a valid redeclaration of a previous enumeration.
 /// \return true if the redeclaration was invalid.
-bool Sema::CheckEnumRedeclaration(
-SourceLocation EnumLoc, bool IsScoped, QualType EnumUnderlyingTy,
-bool EnumUnderlyingIsImplicit, const EnumDecl *Prev) {
-  bool IsFixed = !EnumUnderlyingTy.isNull();
-
+bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped,
+  QualType EnumUnderlyingTy, bool IsFixed,
+  const EnumDecl *Prev) {
   if (IsScoped != Prev->isScoped()) {
 Diag(EnumLoc, diag::err_enum_redeclare_scoped_mismatch)
   << Prev->isScoped();
@@ -13260,10 +13258,6 @@
   << Prev->getIntegerTypeRange();
   return true;
 }
-  } else if (IsFixed && !Prev->isFixed() && EnumUnderlyingIsImplicit) 

[PATCH] D42745: [analyzer] Add support for __builtin_constant_p to BuiltinFunctionChecker

2018-02-09 Thread Felix Kostenzer via Phabricator via cfe-commits
sp4r74n-117 added a comment.

I do not have commit access so it would be great if you could do it for me. 
Thanks.


https://reviews.llvm.org/D42745



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


[PATCH] D43105: [RISCV] Enable __int128_t and uint128_t through clang flag

2018-02-09 Thread Eli Friedman via Phabricator via cfe-commits
efriedma added a comment.

So you want int128_t for compiler-rt itself, so you can use the soft-float 
implementation, but you want to make int128_t opt-in to avoid the possibility 
of someone getting a link error trying to link code built with clang against 
libgcc.a?  That seems a little convoluted, but I guess it's okay.

Not sure I like the name "-fuse-int128"; doesn't really indicate what it's 
doing.  Maybe "-fforce-enable-int128".


Repository:
  rC Clang

https://reviews.llvm.org/D43105



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


r324765 - Remove "CHECK: entry" in test case.

2018-02-09 Thread Akira Hatanaka via cfe-commits
Author: ahatanak
Date: Fri Feb  9 11:25:31 2018
New Revision: 324765

URL: http://llvm.org/viewvc/llvm-project?rev=324765=rev
Log:
Remove "CHECK: entry" in test case.

rdar://problem/37397814

Modified:
cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm

Modified: cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm?rev=324765=324764=324765=diff
==
--- cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm Fri Feb  9 11:25:31 2018
@@ -81,7 +81,6 @@ void testCallStrong(Strong *a) {
 }
 
 // CHECK: define i64 @_Z16testReturnStrongP6Strong(%[[STRUCT_STRONG]]* 
%[[A:.*]])
-// CHECK: entry:
 // CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONG]], align 8
 // CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONG]]*, align 8
 // CHECK: store %[[STRUCT_STRONG]]* %[[A]], %[[STRUCT_STRONG]]** %[[A_ADDR]], 
align 8


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


[PATCH] D30691: [analyzer] Support for naive cross translational unit analysis

2018-02-09 Thread George Karpenkov via Phabricator via cfe-commits
george.karpenkov added a comment.

Python code looks OK to me, I have one last request: could we have a small 
documentation how the whole thing is supposed work in integration, preferably 
on an available open-source project any reader could check out?
I am asking because I have actually tried and failed to launch this CTU patch 
on a project I was analyzing.


https://reviews.llvm.org/D30691



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


[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.

2018-02-09 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb updated this revision to Diff 133660.
bsdjhb added a comment.

- Rebase.
- Rework ABI macro checks.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D39074

Files:
  include/__libunwind_config.h
  src/AddressSpace.hpp
  src/DwarfInstructions.hpp
  src/UnwindRegistersRestore.S
  src/UnwindRegistersSave.S
  src/libunwind.cpp

Index: src/libunwind.cpp
===
--- src/libunwind.cpp
+++ src/libunwind.cpp
@@ -61,9 +61,10 @@
 # define REGISTER_KIND Registers_arm
 #elif defined(__or1k__)
 # define REGISTER_KIND Registers_or1k
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
+defined(__mips_soft_float)
 # define REGISTER_KIND Registers_mips_o32
-#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
+#elif defined(__mips64) && defined(__mips_soft_float)
 # define REGISTER_KIND Registers_mips_newabi
 #elif defined(__mips__)
 # warning The MIPS architecture is not supported with this ABI and environment!
Index: src/UnwindRegistersSave.S
===
--- src/UnwindRegistersSave.S
+++ src/UnwindRegistersSave.S
@@ -116,7 +116,8 @@
   xorl  %eax, %eax# return UNW_ESUCCESS
   ret
 
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
+defined(__mips_soft_float)
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -172,7 +173,7 @@
   or$2, $0, $0
   .set pop
 
-#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
+#elif defined(__mips64) && defined(__mips_soft_float)
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
Index: src/UnwindRegistersRestore.S
===
--- src/UnwindRegistersRestore.S
+++ src/UnwindRegistersRestore.S
@@ -799,7 +799,8 @@
   l.jr r9
l.nop
 
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
+defined(__mips_soft_float)
 
 //
 // void libunwind::Registers_mips_o32::jumpto()
@@ -855,7 +856,7 @@
   lw$4, (4 * 4)($4)
   .set pop
 
-#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
+#elif defined(__mips64) && defined(__mips_soft_float)
 
 //
 // void libunwind::Registers_mips_newabi::jumpto()
Index: src/DwarfInstructions.hpp
===
--- src/DwarfInstructions.hpp
+++ src/DwarfInstructions.hpp
@@ -82,10 +82,10 @@
 const RegisterLocation ) {
   switch (savedReg.location) {
   case CFI_Parser::kRegisterInCFA:
-return addressSpace.getP(cfa + (pint_t)savedReg.value);
+return addressSpace.getRegister(cfa + (pint_t)savedReg.value);
 
   case CFI_Parser::kRegisterAtExpression:
-return addressSpace.getP(
+return addressSpace.getRegister(
 evaluateExpression((pint_t)savedReg.value, addressSpace,
 registers, cfa));
 
Index: src/AddressSpace.hpp
===
--- src/AddressSpace.hpp
+++ src/AddressSpace.hpp
@@ -207,6 +207,7 @@
 return val;
   }
   uintptr_t   getP(pint_t addr);
+  uint64_tgetRegister(pint_t addr);
   static uint64_t getULEB128(pint_t , pint_t end);
   static int64_t  getSLEB128(pint_t , pint_t end);
 
@@ -228,6 +229,14 @@
 #endif
 }
 
+inline uint64_t LocalAddressSpace::getRegister(pint_t addr) {
+#if __SIZEOF_POINTER__ == 8 || defined(__mips64)
+  return get64(addr);
+#else
+  return get32(addr);
+#endif
+}
+
 /// Read a ULEB128 into a 64-bit word.
 inline uint64_t LocalAddressSpace::getULEB128(pint_t , pint_t end) {
   const uint8_t *p = (uint8_t *)addr;
@@ -600,6 +609,7 @@
   uint32_t  get32(pint_t addr);
   uint64_t  get64(pint_t addr);
   pint_tgetP(pint_t addr);
+  uint64_t  getRegister(pint_t addr);
   uint64_t  getULEB128(pint_t , pint_t end);
   int64_t   getSLEB128(pint_t , pint_t end);
   pint_tgetEncodedP(pint_t , pint_t end, uint8_t encoding,
@@ -636,7 +646,12 @@
 }
 
 template 
-uint64_t RemoteAddressSpace::getULEB128(pint_t , pint_t end) {
+typename P::uint_t OtherAddressSpace::getRegister(pint_t addr) {
+  return P::getRegister(*(uint64_t *)localCopy(addr));
+}
+
+template 
+uint64_t OtherAddressSpace::getULEB128(pint_t , pint_t end) {
   uintptr_t size = (end - addr);
   LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
   LocalAddressSpace::pint_t sladdr = laddr;
Index: include/__libunwind_config.h
===
--- include/__libunwind_config.h
+++ include/__libunwind_config.h
@@ -71,11 +71,15 @@
 #  define _LIBUNWIND_CURSOR_SIZE 24
 #  define _LIBUNWIND_HIGHEST_DWARF_REGISTER 

[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.

2018-02-09 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb marked 7 inline comments as done.
bsdjhb added a comment.

Nice sleuthing!


Repository:
  rUNW libunwind

https://reviews.llvm.org/D39074



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


r324762 - [analyzer] [tests] Fixing an error after non-atomic cherry-pick

2018-02-09 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Feb  9 10:48:31 2018
New Revision: 324762

URL: http://llvm.org/viewvc/llvm-project?rev=324762=rev
Log:
[analyzer] [tests] Fixing an error after non-atomic cherry-pick

Modified:
cfe/trunk/utils/analyzer/CmpRuns.py

Modified: cfe/trunk/utils/analyzer/CmpRuns.py
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/CmpRuns.py?rev=324762=324761=324762=diff
==
--- cfe/trunk/utils/analyzer/CmpRuns.py (original)
+++ cfe/trunk/utils/analyzer/CmpRuns.py Fri Feb  9 10:48:31 2018
@@ -29,6 +29,7 @@ Usage:
 import os
 import plistlib
 from math import log
+from optparse import OptionParser
 
 
 # Information about analysis run:


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


[PATCH] D42983: [clang-tidy] Add readability-simd-intrinsics check.

2018-02-09 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added inline comments.



Comment at: clang-tidy/readability/SIMDIntrinsicsCheck.cpp:46
+
+  static const llvm::StringMap Mapping{
+// [simd.alg]

I think you can use `llvm::StringRef` here instead of `std::string`



Comment at: clang-tidy/readability/SIMDIntrinsicsCheck.cpp:88
+: ClangTidyCheck(Name, Context),
+  Enabled(Options.getLocalOrGlobal("Enabled", 0) != 0) {}
+

`Enabled` seems too broad to me.
How about `UseStdExperimental`? (still defaults to `false`) 



Comment at: clang-tidy/readability/SIMDIntrinsicsCheck.cpp:98
+  if (getLangOpts().CPlusPlus2a) {
+Std = "std";
+  } else if (getLangOpts().CPlusPlus11) {

So sorry for beating the same stuff again, but i believe as of right now, it's 
still only in `std::experimental` namespace, not in `std`?



Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42983



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


[PATCH] D43128: Introduce an API for LLDB to compute the default module cache path

2018-02-09 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL324761: Introduce an API for LLDB to compute the default 
module cache path (authored by adrian, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43128?vs=133631=133650#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43128

Files:
  cfe/trunk/include/clang/Driver/Driver.h
  cfe/trunk/lib/Driver/ToolChains/Clang.cpp


Index: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
===
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp
@@ -2500,6 +2500,13 @@
 CmdArgs.push_back("-fno-math-builtin");
 }
 
+void Driver::getDefaultModuleCachePath(SmallVectorImpl ) {
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Result);
+  llvm::sys::path::append(Result, "org.llvm.clang.");
+  appendUserToPath(Result);
+  llvm::sys::path::append(Result, "ModuleCache");
+}
+
 static void RenderModulesOptions(Compilation , const Driver ,
  const ArgList , const InputInfo ,
  const InputInfo ,
@@ -2560,10 +2567,7 @@
   llvm::sys::path::append(Path, "modules");
 } else if (Path.empty()) {
   // No module path was provided: use the default.
-  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);
-  llvm::sys::path::append(Path, "org.llvm.clang.");
-  appendUserToPath(Path);
-  llvm::sys::path::append(Path, "ModuleCache");
+  Driver::getDefaultModuleCachePath(Path);
 }
 
 const char Arg[] = "-fmodules-cache-path=";
Index: cfe/trunk/include/clang/Driver/Driver.h
===
--- cfe/trunk/include/clang/Driver/Driver.h
+++ cfe/trunk/include/clang/Driver/Driver.h
@@ -572,6 +572,8 @@
   /// no extra characters remaining at the end.
   static bool GetReleaseVersion(StringRef Str,
 MutableArrayRef Digits);
+  /// Compute the default -fmodule-cache-path.
+  static void getDefaultModuleCachePath(SmallVectorImpl );
 };
 
 /// \return True if the last defined optimization level is -Ofast.


Index: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
===
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp
@@ -2500,6 +2500,13 @@
 CmdArgs.push_back("-fno-math-builtin");
 }
 
+void Driver::getDefaultModuleCachePath(SmallVectorImpl ) {
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Result);
+  llvm::sys::path::append(Result, "org.llvm.clang.");
+  appendUserToPath(Result);
+  llvm::sys::path::append(Result, "ModuleCache");
+}
+
 static void RenderModulesOptions(Compilation , const Driver ,
  const ArgList , const InputInfo ,
  const InputInfo ,
@@ -2560,10 +2567,7 @@
   llvm::sys::path::append(Path, "modules");
 } else if (Path.empty()) {
   // No module path was provided: use the default.
-  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);
-  llvm::sys::path::append(Path, "org.llvm.clang.");
-  appendUserToPath(Path);
-  llvm::sys::path::append(Path, "ModuleCache");
+  Driver::getDefaultModuleCachePath(Path);
 }
 
 const char Arg[] = "-fmodules-cache-path=";
Index: cfe/trunk/include/clang/Driver/Driver.h
===
--- cfe/trunk/include/clang/Driver/Driver.h
+++ cfe/trunk/include/clang/Driver/Driver.h
@@ -572,6 +572,8 @@
   /// no extra characters remaining at the end.
   static bool GetReleaseVersion(StringRef Str,
 MutableArrayRef Digits);
+  /// Compute the default -fmodule-cache-path.
+  static void getDefaultModuleCachePath(SmallVectorImpl );
 };
 
 /// \return True if the last defined optimization level is -Ofast.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r324761 - Introduce an API for LLDB to compute the default module cache path

2018-02-09 Thread Adrian Prantl via cfe-commits
Author: adrian
Date: Fri Feb  9 10:43:10 2018
New Revision: 324761

URL: http://llvm.org/viewvc/llvm-project?rev=324761=rev
Log:
Introduce an API for LLDB to compute the default module cache path

LLDB creates Clang modules and had an incomplete copy of the clang
Driver code that compute the -fmodule-cache-path. This patch makes the
clang driver code accessible to LLDB.

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

Modified:
cfe/trunk/include/clang/Driver/Driver.h
cfe/trunk/lib/Driver/ToolChains/Clang.cpp

Modified: cfe/trunk/include/clang/Driver/Driver.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=324761=324760=324761=diff
==
--- cfe/trunk/include/clang/Driver/Driver.h (original)
+++ cfe/trunk/include/clang/Driver/Driver.h Fri Feb  9 10:43:10 2018
@@ -572,6 +572,8 @@ public:
   /// no extra characters remaining at the end.
   static bool GetReleaseVersion(StringRef Str,
 MutableArrayRef Digits);
+  /// Compute the default -fmodule-cache-path.
+  static void getDefaultModuleCachePath(SmallVectorImpl );
 };
 
 /// \return True if the last defined optimization level is -Ofast.

Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=324761=324760=324761=diff
==
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Fri Feb  9 10:43:10 2018
@@ -2500,6 +2500,13 @@ static void RenderBuiltinOptions(const T
 CmdArgs.push_back("-fno-math-builtin");
 }
 
+void Driver::getDefaultModuleCachePath(SmallVectorImpl ) {
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Result);
+  llvm::sys::path::append(Result, "org.llvm.clang.");
+  appendUserToPath(Result);
+  llvm::sys::path::append(Result, "ModuleCache");
+}
+
 static void RenderModulesOptions(Compilation , const Driver ,
  const ArgList , const InputInfo ,
  const InputInfo ,
@@ -2560,10 +2567,7 @@ static void RenderModulesOptions(Compila
   llvm::sys::path::append(Path, "modules");
 } else if (Path.empty()) {
   // No module path was provided: use the default.
-  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);
-  llvm::sys::path::append(Path, "org.llvm.clang.");
-  appendUserToPath(Path);
-  llvm::sys::path::append(Path, "ModuleCache");
+  Driver::getDefaultModuleCachePath(Path);
 }
 
 const char Arg[] = "-fmodules-cache-path=";


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


[PATCH] D43098: [analyzer] [tests] [NFC] Remove a fragile tightly-coupled component emulating parser output

2018-02-09 Thread George Karpenkov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC324759: [analyzer] [tests] [NFC] Remove a fragile 
tightly-coupled component emulating… (authored by george.karpenkov, committed 
by ).
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D43098

Files:
  utils/analyzer/CmpRuns.py
  utils/analyzer/SATestBuild.py


Index: utils/analyzer/SATestBuild.py
===
--- utils/analyzer/SATestBuild.py
+++ utils/analyzer/SATestBuild.py
@@ -566,7 +566,8 @@
RefDir, NewDir))
 
 PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName)
-Opts = CmpRuns.CmpOptions(rootA="", rootB=PatchedSourceDirPath)
+Opts, Args = CmpRuns.generate_option_parser().parse_args(
+["", PatchedSourceDirPath])
 # Scan the results, delete empty plist files.
 NumDiffs, ReportsInRef, ReportsInNew = \
 CmpRuns.dumpScanBuildResultsDiff(RefDir, NewDir, Opts, False)
Index: utils/analyzer/CmpRuns.py
===
--- utils/analyzer/CmpRuns.py
+++ utils/analyzer/CmpRuns.py
@@ -102,20 +102,6 @@
 return self._data
 
 
-class CmpOptions:
-"""
-Fake output of option parser with manually constructed options.
-"""
-
-def __init__(self, verboseLog=None, rootA="", rootB=""):
-self.rootA = rootA
-self.rootB = rootB
-self.verboseLog = verboseLog
-self.relative_path_histogram = False
-self.relative_log_path_histogram = False
-self.absolute_path_histogram = False
-
-
 class AnalysisReport:
 def __init__(self, run, files):
 self.run = run
@@ -322,9 +308,7 @@
 
 return foundDiffs, len(resultsA.diagnostics), len(resultsB.diagnostics)
 
-
-def main():
-from optparse import OptionParser
+def generate_option_parser():
 parser = OptionParser("usage: %prog [options] [dir A] [dir B]")
 parser.add_option("", "--rootA", dest="rootA",
   help="Prefix to ignore on source files for directory A",
@@ -334,24 +318,29 @@
   action="store", type=str, default="")
 parser.add_option("", "--verbose-log", dest="verboseLog",
   help="Write additional information to LOG \
-  [default=None]",
+   [default=None]",
   action="store", type=str, default=None,
   metavar="LOG")
 parser.add_option("--relative-path-differences-histogram",
   action="store_true", dest="relative_path_histogram",
   default=False,
   help="Show histogram of relative paths differences. \
-  Requires matplotlib")
+Requires matplotlib")
 parser.add_option("--relative-log-path-differences-histogram",
   action="store_true", dest="relative_log_path_histogram",
   default=False,
   help="Show histogram of log relative paths differences. \
-  Requires matplotlib")
+Requires matplotlib")
 parser.add_option("--absolute-path-differences-histogram",
   action="store_true", dest="absolute_path_histogram",
   default=False,
   help="Show histogram of absolute paths differences. \
-  Requires matplotlib")
+Requires matplotlib")
+return parser
+
+
+def main():
+parser = generate_option_parser()
 (opts, args) = parser.parse_args()
 
 if len(args) != 2:


Index: utils/analyzer/SATestBuild.py
===
--- utils/analyzer/SATestBuild.py
+++ utils/analyzer/SATestBuild.py
@@ -566,7 +566,8 @@
RefDir, NewDir))
 
 PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName)
-Opts = CmpRuns.CmpOptions(rootA="", rootB=PatchedSourceDirPath)
+Opts, Args = CmpRuns.generate_option_parser().parse_args(
+["", PatchedSourceDirPath])
 # Scan the results, delete empty plist files.
 NumDiffs, ReportsInRef, ReportsInNew = \
 CmpRuns.dumpScanBuildResultsDiff(RefDir, NewDir, Opts, False)
Index: utils/analyzer/CmpRuns.py
===
--- utils/analyzer/CmpRuns.py
+++ utils/analyzer/CmpRuns.py
@@ -102,20 +102,6 @@
 return self._data
 
 
-class CmpOptions:
-"""
-Fake output of option parser with manually constructed options.
-"""
-
-def __init__(self, verboseLog=None, rootA="", rootB=""):
-self.rootA = rootA
-self.rootB = rootB
-self.verboseLog = verboseLog
-self.relative_path_histogram = False
-

r324759 - [analyzer] [tests] [NFC] Remove a fragile tightly-coupled component emulating parser output

2018-02-09 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Feb  9 10:39:47 2018
New Revision: 324759

URL: http://llvm.org/viewvc/llvm-project?rev=324759=rev
Log:
[analyzer] [tests] [NFC] Remove a fragile tightly-coupled component emulating 
parser output

...when we can just use the real parser instead.

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

Modified:
cfe/trunk/utils/analyzer/CmpRuns.py
cfe/trunk/utils/analyzer/SATestBuild.py

Modified: cfe/trunk/utils/analyzer/CmpRuns.py
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/CmpRuns.py?rev=324759=324758=324759=diff
==
--- cfe/trunk/utils/analyzer/CmpRuns.py (original)
+++ cfe/trunk/utils/analyzer/CmpRuns.py Fri Feb  9 10:39:47 2018
@@ -102,20 +102,6 @@ class AnalysisDiagnostic:
 return self._data
 
 
-class CmpOptions:
-"""
-Fake output of option parser with manually constructed options.
-"""
-
-def __init__(self, verboseLog=None, rootA="", rootB=""):
-self.rootA = rootA
-self.rootB = rootB
-self.verboseLog = verboseLog
-self.relative_path_histogram = False
-self.relative_log_path_histogram = False
-self.absolute_path_histogram = False
-
-
 class AnalysisReport:
 def __init__(self, run, files):
 self.run = run
@@ -322,9 +308,7 @@ def dumpScanBuildResultsDiff(dirA, dirB,
 
 return foundDiffs, len(resultsA.diagnostics), len(resultsB.diagnostics)
 
-
-def main():
-from optparse import OptionParser
+def generate_option_parser():
 parser = OptionParser("usage: %prog [options] [dir A] [dir B]")
 parser.add_option("", "--rootA", dest="rootA",
   help="Prefix to ignore on source files for directory A",
@@ -334,24 +318,29 @@ def main():
   action="store", type=str, default="")
 parser.add_option("", "--verbose-log", dest="verboseLog",
   help="Write additional information to LOG \
-  [default=None]",
+   [default=None]",
   action="store", type=str, default=None,
   metavar="LOG")
 parser.add_option("--relative-path-differences-histogram",
   action="store_true", dest="relative_path_histogram",
   default=False,
   help="Show histogram of relative paths differences. \
-  Requires matplotlib")
+Requires matplotlib")
 parser.add_option("--relative-log-path-differences-histogram",
   action="store_true", dest="relative_log_path_histogram",
   default=False,
   help="Show histogram of log relative paths differences. \
-  Requires matplotlib")
+Requires matplotlib")
 parser.add_option("--absolute-path-differences-histogram",
   action="store_true", dest="absolute_path_histogram",
   default=False,
   help="Show histogram of absolute paths differences. \
-  Requires matplotlib")
+Requires matplotlib")
+return parser
+
+
+def main():
+parser = generate_option_parser()
 (opts, args) = parser.parse_args()
 
 if len(args) != 2:

Modified: cfe/trunk/utils/analyzer/SATestBuild.py
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/SATestBuild.py?rev=324759=324758=324759=diff
==
--- cfe/trunk/utils/analyzer/SATestBuild.py (original)
+++ cfe/trunk/utils/analyzer/SATestBuild.py Fri Feb  9 10:39:47 2018
@@ -566,7 +566,8 @@ def runCmpResults(Dir, Strictness=0):
RefDir, NewDir))
 
 PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName)
-Opts = CmpRuns.CmpOptions(rootA="", rootB=PatchedSourceDirPath)
+Opts, Args = CmpRuns.generate_option_parser().parse_args(
+["", PatchedSourceDirPath])
 # Scan the results, delete empty plist files.
 NumDiffs, ReportsInRef, ReportsInNew = \
 CmpRuns.dumpScanBuildResultsDiff(RefDir, NewDir, Opts, False)


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


[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown

2018-02-09 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:24
+
+  auto CtorInitializerList =
+  cxxConstructorDecl(hasAnyConstructorInitializer(anything()));

Eugene.Zelenko wrote:
> Please don't use auto where type could not be easily deduced.
`auto` is appropriate here because these are horrible to try to spell out 
manually.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43120



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


[PATCH] D43128: Introduce an API for LLDB to compute the default module cache path

2018-02-09 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno accepted this revision.
bruno added a comment.
This revision is now accepted and ready to land.

LGTM


https://reviews.llvm.org/D43128



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


[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown

2018-02-09 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:24
+
+  auto CtorInitializerList =
+  cxxConstructorDecl(hasAnyConstructorInitializer(anything()));

Please don't use auto where type could not be easily deduced.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43120



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


[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown

2018-02-09 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: docs/clang-tidy/checks/misc-throw-keyword-missing.rst:6
+
+This check warns about the potentially missing `throw` keyword. If a temporary 
object is created,
+but the object's type derives from (or the same as) a class that has 
'EXCEPTION', 'Exception' or

aaron.ballman wrote:
> about the potentially -> about a potentially
Please remove //This check// and enclose throw in ``


https://reviews.llvm.org/D43120



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


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-02-09 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

ping?


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



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


[PATCH] D42969: [Sema] Fix decltype of static data members

2018-02-09 Thread Roger Ferrer Ibanez via Phabricator via cfe-commits
rogfer01 accepted this revision.
rogfer01 added a comment.
This revision is now accepted and ready to land.

This LGTM. Thanks for fixing this.

Wait a couple of days before committing in case there are other comments.


https://reviews.llvm.org/D42969



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


[PATCH] D42640: [clangd] collect symbol #include & insert #include in global code completion.

2018-02-09 Thread Eric Liu via Phabricator via cfe-commits
ioeric added inline comments.



Comment at: clangd/ClangdServer.cpp:368
 
+/// Calculates the shortest possible include path when inserting \p Header to 
\p
+/// File, by matching \p Header against all include search directories for \p

sammccall wrote:
> ioeric wrote:
> > sammccall wrote:
> > > This has a fair amount of logic (well, plumbing :-D) and uses relatively 
> > > little from ClangdServer.
> > > Can we move `shortenIncludePath` to a separate file and pass in the FS 
> > > and command?
> > > 
> > > I'd suggest maybe `Headers.h` - The formatting part of `insertInclude` 
> > > could also fit there, as well as probably the logic from 
> > > `switchSourceHeader` I think (the latter not in this patch of course).
> > > 
> > > This won't really help much with testing, I just find it gets hard to 
> > > navigate files that have lots of details of unrelated features. 
> > > ClangdUnit and ClangdServer both have this potential to grow without 
> > > bound, though they're in reasonable shape now. Interested what you think!
> > Done.
> > 
> > I didn't move the formatting code, as half of the code is pulling out the 
> > style, which we might want to share/change depending on other clangd logics 
> > that might use style.
> I'd still think pulling out `Expected 
> insertInclude(File, Code, Header, VFS, Style)` would be worthwhile here - the 
> formatting isn't a lot of code, but it's a bit magic, plus the quote 
> handling... it's a bit of code. It'd make it more obvious what the 
> interactions with ClangdServer's state are. But up to you, we can always do 
> this later.
So it's just 2 lines for the replacement magic (+1 for comment) now after 
removing some redundant code. 

I like `shortenIncludePath` better because it's more self-contained and easier 
to write tests against, and `insertInclude` doesn't seem to carry much more 
weight while we would need to handle `replacements` logic which has been tested 
in the tests.



Comment at: clangd/ClangdServer.cpp:370
+/// File, by matching \p Header against all include search directories for \p
+/// File via `clang::HeaderSearch`.
+///

sammccall wrote:
> sammccall wrote:
> > maybe drop "via clang::HeaderSearch" (it's doc'd in the implementation) and 
> > add an example?
> > 
> > It might be worth explicitly stating that the result is an #include string 
> > (with quotes) - you just call it a "path" here.
> > 
> > "shortest" makes sense as a first implementation, but we may want to 
> > document something more like "best" - I know there are codebases we care 
> > about where file-relative paths are banned. Also I suspect we don't give 
> > "../../../../Foo.h" even if it's shortest :-)
> > "shortest" makes sense as a first implementation, but we may want to 
> > document something more like "best" - I know there are codebases we care 
> > about where file-relative paths are banned. Also I suspect we don't give 
> > "../../../../Foo.h" even if it's shortest :-)
> 
> I think this part wasn't addressed
I added a comment for this in the header. But I might be misunderstanding you 
suggestion. Did you mean we need a better name for the function?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42640



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


[PATCH] D42640: [clangd] collect symbol #include & insert #include in global code completion.

2018-02-09 Thread Eric Liu via Phabricator via cfe-commits
ioeric updated this revision to Diff 133635.
ioeric marked 3 inline comments as done.
ioeric added a comment.

- Addressed review comments.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42640

Files:
  clangd/CMakeLists.txt
  clangd/ClangdLSPServer.cpp
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/CodeComplete.cpp
  clangd/Headers.cpp
  clangd/Headers.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/clients/clangd-vscode/package.json
  clangd/global-symbol-builder/CMakeLists.txt
  clangd/global-symbol-builder/GlobalSymbolBuilderMain.cpp
  clangd/index/CanonicalIncludes.cpp
  clangd/index/CanonicalIncludes.h
  clangd/index/Index.cpp
  clangd/index/Index.h
  clangd/index/Merge.cpp
  clangd/index/SymbolCollector.cpp
  clangd/index/SymbolCollector.h
  clangd/index/SymbolYAML.cpp
  clangd/tool/ClangdMain.cpp
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test
  test/clangd/insert-include.test
  unittests/clangd/CMakeLists.txt
  unittests/clangd/ClangdTests.cpp
  unittests/clangd/HeadersTests.cpp
  unittests/clangd/SymbolCollectorTests.cpp

Index: unittests/clangd/SymbolCollectorTests.cpp
===
--- unittests/clangd/SymbolCollectorTests.cpp
+++ unittests/clangd/SymbolCollectorTests.cpp
@@ -47,6 +47,12 @@
 }
 MATCHER_P(QName, Name, "") { return (arg.Scope + arg.Name).str() == Name; }
 MATCHER_P(DeclURI, P, "") { return arg.CanonicalDeclaration.FileURI == P; }
+MATCHER(HasIncludeHeader, "") {
+  return arg.Detail && !arg.Detail->IncludeHeader.empty();
+}
+MATCHER_P(IncludeHeader, P, "") {
+  return arg.Detail && arg.Detail->IncludeHeader == P;
+}
 MATCHER_P(LocationOffsets, Offsets, "") {
   // Offset range in SymbolLocation is [start, end] while in Clangd is [start,
   // end).
@@ -60,41 +66,62 @@
 namespace {
 class SymbolIndexActionFactory : public tooling::FrontendActionFactory {
 public:
-  SymbolIndexActionFactory(SymbolCollector::Options COpts)
-  : COpts(std::move(COpts)) {}
+  SymbolIndexActionFactory(SymbolCollector::Options COpts,
+   CommentHandler *PragmaHandler)
+  : COpts(std::move(COpts)), PragmaHandler(PragmaHandler) {}
 
   clang::FrontendAction *create() override {
+class WrappedIndexAction : public WrapperFrontendAction {
+public:
+  WrappedIndexAction(std::shared_ptr C,
+ const index::IndexingOptions ,
+ CommentHandler *PragmaHandler)
+  : WrapperFrontendAction(
+index::createIndexingAction(C, Opts, nullptr)),
+PragmaHandler(PragmaHandler) {}
+
+  std::unique_ptr
+  CreateASTConsumer(CompilerInstance , StringRef InFile) override {
+if (PragmaHandler)
+  CI.getPreprocessor().addCommentHandler(PragmaHandler);
+return WrapperFrontendAction::CreateASTConsumer(CI, InFile);
+  }
+
+private:
+  index::IndexingOptions IndexOpts;
+  CommentHandler *PragmaHandler;
+};
 index::IndexingOptions IndexOpts;
 IndexOpts.SystemSymbolFilter =
 index::IndexingOptions::SystemSymbolFilterKind::All;
 IndexOpts.IndexFunctionLocals = false;
 Collector = std::make_shared(COpts);
-FrontendAction *Action =
-index::createIndexingAction(Collector, IndexOpts, nullptr).release();
-return Action;
+return new WrappedIndexAction(Collector, std::move(IndexOpts),
+  PragmaHandler);
   }
 
   std::shared_ptr Collector;
   SymbolCollector::Options COpts;
+  CommentHandler *PragmaHandler;
 };
 
 class SymbolCollectorTest : public ::testing::Test {
 public:
   SymbolCollectorTest()
-  : TestHeaderName(getVirtualTestFilePath("symbol.h").str()),
+  : InMemoryFileSystem(new vfs::InMemoryFileSystem),
+TestHeaderName(getVirtualTestFilePath("symbol.h").str()),
 TestFileName(getVirtualTestFilePath("symbol.cc").str()) {
 TestHeaderURI = URI::createFile(TestHeaderName).toString();
 TestFileURI = URI::createFile(TestFileName).toString();
   }
 
   bool runSymbolCollector(StringRef HeaderCode, StringRef MainCode,
   const std::vector  = {}) {
-llvm::IntrusiveRefCntPtr InMemoryFileSystem(
-new vfs::InMemoryFileSystem);
 llvm::IntrusiveRefCntPtr Files(
 new FileManager(FileSystemOptions(), InMemoryFileSystem));
 
-auto Factory = llvm::make_unique(CollectorOpts);
+auto Factory = llvm::make_unique(
+CollectorOpts, PragmaHandler.get());
 
 std::vector Args = {"symbol_collector", "-fsyntax-only",
  "-std=c++11", TestFileName};
@@ -120,12 +147,14 @@
   }
 
 protected:
+  llvm::IntrusiveRefCntPtr InMemoryFileSystem;
   std::string TestHeaderName;
   std::string TestHeaderURI;
   std::string TestFileName;
   std::string TestFileURI;
   SymbolSlab Symbols;
   SymbolCollector::Options CollectorOpts;
+  std::unique_ptr PragmaHandler;
 };
 
 

[PATCH] D42895: [libclang] Add `CXSymbolRole role` to CXIdxEntityRefInfo

2018-02-09 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay updated this revision to Diff 133632.
MaskRay added a comment.

Bring back refkind:


Repository:
  rC Clang

https://reviews.llvm.org/D42895

Files:
  include/clang-c/Index.h
  include/clang/Index/IndexSymbol.h
  test/Index/index-refs.cpp
  test/Index/index-subscripting-literals.m
  tools/c-index-test/c-index-test.c
  tools/libclang/CXIndexDataConsumer.cpp
  tools/libclang/CXIndexDataConsumer.h

Index: tools/libclang/CXIndexDataConsumer.h
===
--- tools/libclang/CXIndexDataConsumer.h
+++ tools/libclang/CXIndexDataConsumer.h
@@ -436,13 +436,15 @@
const NamedDecl *Parent,
const DeclContext *DC,
const Expr *E = nullptr,
-   CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
+   CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct,
+   CXSymbolRole Role = CXSymbolRole_None);
 
   bool handleReference(const NamedDecl *D, SourceLocation Loc,
const NamedDecl *Parent,
const DeclContext *DC,
const Expr *E = nullptr,
-   CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
+   CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct,
+   CXSymbolRole Role = CXSymbolRole_None);
 
   bool isNotFromSourceFile(SourceLocation Loc) const;
 
Index: tools/libclang/CXIndexDataConsumer.cpp
===
--- tools/libclang/CXIndexDataConsumer.cpp
+++ tools/libclang/CXIndexDataConsumer.cpp
@@ -148,6 +148,11 @@
 return true;
   }
 };
+
+CXSymbolRole getSymbolRole(SymbolRoleSet Role) {
+  // CXSymbolRole mirrors low 9 bits of clang::index::SymbolRole.
+  return CXSymbolRole(static_cast(Role) & ((1 << 9) - 1));
+}
 }
 
 bool CXIndexDataConsumer::handleDeclOccurence(const Decl *D,
@@ -184,6 +189,7 @@
 if (Roles & (unsigned)SymbolRole::Implicit) {
   Kind = CXIdxEntityRef_Implicit;
 }
+CXSymbolRole CXRole = getSymbolRole(Roles);
 
 CXCursor Cursor;
 if (ASTNode.OrigE) {
@@ -202,7 +208,7 @@
 }
 handleReference(ND, Loc, Cursor,
 dyn_cast_or_null(ASTNode.Parent),
-ASTNode.ContainerDC, ASTNode.OrigE, Kind);
+ASTNode.ContainerDC, ASTNode.OrigE, Kind, CXRole);
 
   } else {
 const DeclContext *LexicalDC = ASTNode.ContainerDC;
@@ -889,21 +895,23 @@
   const NamedDecl *Parent,
   const DeclContext *DC,
   const Expr *E,
-  CXIdxEntityRefKind Kind) {
+  CXIdxEntityRefKind Kind,
+  CXSymbolRole Role) {
   if (!D || !DC)
 return false;
 
   CXCursor Cursor = E ? MakeCXCursor(E, cast(DC), CXTU)
   : getRefCursor(D, Loc);
-  return handleReference(D, Loc, Cursor, Parent, DC, E, Kind);
+  return handleReference(D, Loc, Cursor, Parent, DC, E, Kind, Role);
 }
 
 bool CXIndexDataConsumer::handleReference(const NamedDecl *D, SourceLocation Loc,
   CXCursor Cursor,
   const NamedDecl *Parent,
   const DeclContext *DC,
   const Expr *E,
-  CXIdxEntityRefKind Kind) {
+  CXIdxEntityRefKind Kind,
+  CXSymbolRole Role) {
   if (!CB.indexEntityReference)
 return false;
 
@@ -939,7 +947,8 @@
   getIndexLoc(Loc),
   ,
   Parent ?  : nullptr,
-   };
+  ,
+  Role };
   CB.indexEntityReference(ClientData, );
   return true;
 }
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -3326,6 +3326,27 @@
   }
 }
 
+static void printSymbolRole(CXSymbolRole role) {
+  if (role & CXSymbolRole_Declaration)
+printf(" decl");
+  if (role & CXSymbolRole_Definition)
+printf(" def");
+  if (role & CXSymbolRole_Reference)
+printf(" ref");
+  if (role & CXSymbolRole_Read)
+printf(" read");
+  if (role & CXSymbolRole_Write)
+printf(" write");
+  if (role & CXSymbolRole_Call)
+printf(" call");
+  if (role & CXSymbolRole_Dynamic)
+printf(" dyn");
+  if (role & CXSymbolRole_AddressOf)
+printf(" addr");
+  if (role & CXSymbolRole_Implicit)
+printf(" implicit");
+}
+
 static void index_diagnostic(CXClientData client_data,
  CXDiagnosticSet diagSet, void *reserved) {
   

[PATCH] D43128: Introduce an API for LLDB to compute the default module cache path

2018-02-09 Thread Adrian Prantl via Phabricator via cfe-commits
aprantl created this revision.
aprantl added reviewers: bruno, jingham.

LLDB creates Clang modules and had an incomplete copy of the clang Driver code 
that compute the -fmodule-cache-path. This patch makes the clang driver code 
accessible to LLDB.


https://reviews.llvm.org/D43128

Files:
  include/clang/Driver/Driver.h
  lib/Driver/ToolChains/Clang.cpp


Index: lib/Driver/ToolChains/Clang.cpp
===
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -2500,6 +2500,13 @@
 CmdArgs.push_back("-fno-math-builtin");
 }
 
+void Driver::getDefaultModuleCachePath(SmallVectorImpl ) {
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Result);
+  llvm::sys::path::append(Result, "org.llvm.clang.");
+  appendUserToPath(Result);
+  llvm::sys::path::append(Result, "ModuleCache");
+}
+
 static void RenderModulesOptions(Compilation , const Driver ,
  const ArgList , const InputInfo ,
  const InputInfo ,
@@ -2560,10 +2567,7 @@
   llvm::sys::path::append(Path, "modules");
 } else if (Path.empty()) {
   // No module path was provided: use the default.
-  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);
-  llvm::sys::path::append(Path, "org.llvm.clang.");
-  appendUserToPath(Path);
-  llvm::sys::path::append(Path, "ModuleCache");
+  Driver::getDefaultModuleCachePath(Path);
 }
 
 const char Arg[] = "-fmodules-cache-path=";
Index: include/clang/Driver/Driver.h
===
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -572,6 +572,8 @@
   /// no extra characters remaining at the end.
   static bool GetReleaseVersion(StringRef Str,
 MutableArrayRef Digits);
+  /// Compute the default -fmodule-cache-path.
+  static void getDefaultModuleCachePath(SmallVectorImpl );
 };
 
 /// \return True if the last defined optimization level is -Ofast.


Index: lib/Driver/ToolChains/Clang.cpp
===
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -2500,6 +2500,13 @@
 CmdArgs.push_back("-fno-math-builtin");
 }
 
+void Driver::getDefaultModuleCachePath(SmallVectorImpl ) {
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Result);
+  llvm::sys::path::append(Result, "org.llvm.clang.");
+  appendUserToPath(Result);
+  llvm::sys::path::append(Result, "ModuleCache");
+}
+
 static void RenderModulesOptions(Compilation , const Driver ,
  const ArgList , const InputInfo ,
  const InputInfo ,
@@ -2560,10 +2567,7 @@
   llvm::sys::path::append(Path, "modules");
 } else if (Path.empty()) {
   // No module path was provided: use the default.
-  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);
-  llvm::sys::path::append(Path, "org.llvm.clang.");
-  appendUserToPath(Path);
-  llvm::sys::path::append(Path, "ModuleCache");
+  Driver::getDefaultModuleCachePath(Path);
 }
 
 const char Arg[] = "-fmodules-cache-path=";
Index: include/clang/Driver/Driver.h
===
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -572,6 +572,8 @@
   /// no extra characters remaining at the end.
   static bool GetReleaseVersion(StringRef Str,
 MutableArrayRef Digits);
+  /// Compute the default -fmodule-cache-path.
+  static void getDefaultModuleCachePath(SmallVectorImpl );
 };
 
 /// \return True if the last defined optimization level is -Ofast.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r324748 - AMDGPU: Update for datalayout change

2018-02-09 Thread Matt Arsenault via cfe-commits
Author: arsenm
Date: Fri Feb  9 08:58:41 2018
New Revision: 324748

URL: http://llvm.org/viewvc/llvm-project?rev=324748=rev
Log:
AMDGPU: Update for datalayout change

Modified:
cfe/trunk/lib/Basic/Targets/AMDGPU.cpp
cfe/trunk/test/CodeGen/target-data.c
cfe/trunk/test/CodeGenOpenCL/amdgpu-env-amdgiz.cl

Modified: cfe/trunk/lib/Basic/Targets/AMDGPU.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/AMDGPU.cpp?rev=324748=324747=324748=diff
==
--- cfe/trunk/lib/Basic/Targets/AMDGPU.cpp (original)
+++ cfe/trunk/lib/Basic/Targets/AMDGPU.cpp Fri Feb  9 08:58:41 2018
@@ -33,12 +33,12 @@ static const char *const DataLayoutStrin
 "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5";
 
 static const char *const DataLayoutStringSIPrivateIsZero =
-"e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32"
+"e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
 "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
 "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
 
 static const char *const DataLayoutStringSIGenericIsZero =
-"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32"
+"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32-p6:32:32"
 "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
 "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5";
 
@@ -144,7 +144,7 @@ const char *const AMDGPUTargetInfo::GCCR
   "s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111", "s112",
   "s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121",
   "s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc",
-  "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi", 
+  "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi",
   "flat_scratch_lo", "flat_scratch_hi"
 };
 

Modified: cfe/trunk/test/CodeGen/target-data.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/target-data.c?rev=324748=324747=324748=diff
==
--- cfe/trunk/test/CodeGen/target-data.c (original)
+++ cfe/trunk/test/CodeGen/target-data.c Fri Feb  9 08:58:41 2018
@@ -132,12 +132,12 @@
 
 // RUN: %clang_cc1 -triple amdgcn-unknown -target-cpu hawaii -o - -emit-llvm 
%s \
 // RUN: | FileCheck %s -check-prefix=R600SI
-// R600SI: target datalayout = 
"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"
+// R600SI: target datalayout = 
"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"
 
 // Test default -target-cpu
 // RUN: %clang_cc1 -triple amdgcn-unknown -o - -emit-llvm %s \
 // RUN: | FileCheck %s -check-prefix=R600SIDefault
-// R600SIDefault: target datalayout = 
"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"
+// R600SIDefault: target datalayout = 
"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"
 
 // RUN: %clang_cc1 -triple arm64-unknown -o - -emit-llvm %s | \
 // RUN: FileCheck %s -check-prefix=AARCH64

Modified: cfe/trunk/test/CodeGenOpenCL/amdgpu-env-amdgiz.cl
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/amdgpu-env-amdgiz.cl?rev=324748=324747=324748=diff
==
--- cfe/trunk/test/CodeGenOpenCL/amdgpu-env-amdgiz.cl (original)
+++ cfe/trunk/test/CodeGenOpenCL/amdgpu-env-amdgiz.cl Fri Feb  9 08:58:41 2018
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 %s -O0 -triple amdgcn -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 %s -O0 -triple amdgcn---opencl -emit-llvm -o - | FileCheck 
%s
 
-// CHECK: target datalayout = 
"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"
+// CHECK: target datalayout = 
"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"
 void foo(void) {}


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


[PATCH] D43012: [ASTImporter] Fix lexical DC for templated decls; support VarTemplatePartialSpecDecl

2018-02-09 Thread Aleksei Sidorin via Phabricator via cfe-commits
a.sidorin updated this revision to Diff 133626.
a.sidorin marked an inline comment as done.
a.sidorin added a comment.

Fix style issues found on review.


Repository:
  rC Clang

https://reviews.llvm.org/D43012

Files:
  lib/AST/ASTImporter.cpp
  test/ASTMerge/var-cpp/Inputs/var1.cpp
  test/ASTMerge/var-cpp/test.cpp
  unittests/AST/ASTImporterTest.cpp

Index: unittests/AST/ASTImporterTest.cpp
===
--- unittests/AST/ASTImporterTest.cpp
+++ unittests/AST/ASTImporterTest.cpp
@@ -542,20 +542,32 @@
 
 TEST(ImportType, ImportTypeAliasTemplate) {
   MatchVerifier Verifier;
-  testImport("template "
- "struct dummy { static const int i = K; };"
- "template  using dummy2 = dummy;"
- "int declToImport() { return dummy2<3>::i; }",
- Lang_CXX11, "", Lang_CXX11, Verifier,
- functionDecl(
-   hasBody(
- compoundStmt(
-   has(
- returnStmt(
-   has(
- implicitCastExpr(
-   has(
- declRefExpr());
+  testImport(
+  "template "
+  "struct dummy { static const int i = K; };"
+  "template  using dummy2 = dummy;"
+  "int declToImport() { return dummy2<3>::i; }",
+  Lang_CXX11, "", Lang_CXX11, Verifier,
+  functionDecl(
+  hasBody(compoundStmt(
+  has(returnStmt(has(implicitCastExpr(has(declRefExpr(,
+  unless(hasAncestor(translationUnitDecl(has(typeAliasDecl()));
+}
+
+const internal::VariadicDynCastAllOfMatcher
+varTemplateSpecializationDecl;
+
+TEST(ImportDecl, ImportVarTemplate) {
+  MatchVerifier Verifier;
+  testImport(
+  "template "
+  "T pi = T(3.1415926535897932385L);"
+  "void declToImport() { pi; }",
+  Lang_CXX11, "", Lang_CXX11, Verifier,
+  functionDecl(
+  hasBody(has(declRefExpr(to(varTemplateSpecializationDecl(),
+  unless(hasAncestor(translationUnitDecl(has(varDecl(
+  hasName("pi"), unless(varTemplateSpecializationDecl();
 }
 
 TEST(ImportType, ImportPackExpansion) {
Index: test/ASTMerge/var-cpp/test.cpp
===
--- /dev/null
+++ test/ASTMerge/var-cpp/test.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -std=c++17 -o %t.1.ast %S/Inputs/var1.cpp
+// RUN: %clang_cc1 -std=c++17 -ast-merge %t.1.ast -fsyntax-only %s 2>&1
+
+static_assert(my_pi == (double)3.1415926535897932385L);
+static_assert(my_pi == '3');
+
+static_assert(Wrapper::my_const == 1.f);
+static_assert(Wrapper::my_const == nullptr);
+static_assert(Wrapper::my_const == a);
Index: test/ASTMerge/var-cpp/Inputs/var1.cpp
===
--- /dev/null
+++ test/ASTMerge/var-cpp/Inputs/var1.cpp
@@ -0,0 +1,17 @@
+
+template 
+constexpr T my_pi = T(3.1415926535897932385L);  // variable template
+
+template <> constexpr char my_pi = '3';   // variable template specialization
+
+template 
+struct Wrapper {
+  template  static constexpr U my_const = U(1);
+   // Variable template partial specialization with member variable.
+  template  static constexpr U *my_const = (U *)(0);
+};
+
+constexpr char a[] = "hello";
+
+template <> template <>
+constexpr const char *Wrapper::my_const = a;
Index: lib/AST/ASTImporter.cpp
===
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -23,7 +23,6 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include 
 
 namespace clang {
   class ASTNodeImporter : public TypeVisitor,
@@ -1335,6 +1334,21 @@
   return false;
 }
 
+template <>
+bool ASTNodeImporter::ImportTemplateArgumentListInfo(
+const TemplateArgumentListInfo , TemplateArgumentListInfo ) {
+  return ImportTemplateArgumentListInfo(
+  From.getLAngleLoc(), From.getRAngleLoc(), From.arguments(), Result);
+}
+
+template <>
+bool ASTNodeImporter::ImportTemplateArgumentListInfo<
+ASTTemplateArgumentListInfo>(const ASTTemplateArgumentListInfo ,
+ TemplateArgumentListInfo ) {
+  return ImportTemplateArgumentListInfo(From.LAngleLoc, From.RAngleLoc,
+From.arguments(), Result);
+}
+
 bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, 
 RecordDecl *ToRecord, bool Complain) {
   // Eliminate a potential failure point where we attempt to re-import
@@ -1655,10 +1669,8 @@
   SourceLocation StartL = Importer.Import(D->getLocStart());
   TypedefNameDecl *ToTypedef;
   if (IsAlias)
-ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC,
-  StartL, Loc,
- 

[PATCH] D43012: [ASTImporter] Fix lexical DC for templated decls; support VarTemplatePartialSpecDecl

2018-02-09 Thread Aleksei Sidorin via Phabricator via cfe-commits
a.sidorin marked 2 inline comments as done.
a.sidorin added inline comments.



Comment at: lib/AST/ASTImporter.cpp:4296
   // Create the declaration that is being templated.
-  SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
-  SourceLocation IdLoc = Importer.Import(DTemplated->getLocation());
-  TypeSourceInfo *TInfo = Importer.Import(DTemplated->getTypeSourceInfo());
-  VarDecl *D2Templated = VarDecl::Create(Importer.getToContext(), DC, StartLoc,
- IdLoc, Name.getAsIdentifierInfo(), T,
- TInfo, DTemplated->getStorageClass());
-  D2Templated->setAccess(DTemplated->getAccess());
-  
D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
-  D2Templated->setLexicalDeclContext(LexicalDC);
-
-  // Importer.Imported(DTemplated, D2Templated);
-  // LexicalDC->addDeclInternal(D2Templated);
-
-  // Merge the initializer.
-  if (ImportDefinition(DTemplated, D2Templated))
+  VarDecl *ToTemplated = 
dyn_cast_or_null(Importer.Import(DTemplated));
+  if (!ToTemplated)

xazax.hun wrote:
> `auto *` to not repeat type.
I usually prefer to keep the type if it doesn't give a large space win because 
it hurts readability a bit. From `VarDecl *`, we can instantly find the type; 
for `auto`, we have to look forward. (Yes, VarTemplatePartialSpecializationDecl 
has to be replaced immediately :) ).
Other issue is that QtCreator I use for development still doesn't have an 
autocompletion for auto types. However, LLVM says: "do use auto with 
initializers like cast(...)", so I'll change this.



Repository:
  rC Clang

https://reviews.llvm.org/D43012



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


[PATCH] D43114: clang-format: fix formatting of ObjC @synchronized blocks

2018-02-09 Thread Francois Ferrand via Phabricator via cfe-commits
Typz added inline comments.



Comment at: lib/Format/UnwrappedLineParser.cpp:1130
+if (FormatTok->Tok.is(tok::l_brace)) {
+  if (Style.BraceWrapping.AfterObjCDeclaration)
+addUnwrappedLine();

benhamilton wrote:
> Typz wrote:
> > Wondering if formatting with this style is appropriate: the clang-format 
> > doc points in that direction, but it seems to me both `@synchronized` and 
> > `@autoreleasepool` are more akin to "control statements".
> > 
> > For consistency (esp. in ObjC++ code), as a user, I would tend to have 
> > these blocks indented like control statements while 
> > interfaces/implementations blocks would be indented like classes/structs.
> > 
> > So maybe it would be better to introduce a new BraceWrapping style 
> > 'AfterObjCSpecialBlock` to control these cases, matching the possibilities 
> > that are given for control statements vs classes. What do you think?
> Hmm, I definitely agree with that logic. I don't see them acting as 
> declarations in any way, they are definitely like control statements.
> 
Ok, i can change this. Two questions though:
* Should I do this in this patch, or a separate patch? (won't be a big change 
in any case, but it can still be seen as 2 separate issues/changes)
* Should I introduce a new BraceWrapping flag (`AfterObjCSpecialBlock`), or 
simply apply `AfterControlStatement` to these blocks?


Repository:
  rC Clang

https://reviews.llvm.org/D43114



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


[PATCH] D43075: [clang-move] Don't dump macro symbols.

2018-02-09 Thread Haojian Wu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rCTE324742: [clang-move] Dont dump macro symbols. 
(authored by hokein, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D43075?vs=133621=133623#toc

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43075

Files:
  clang-move/ClangMove.cpp
  unittests/clang-move/ClangMoveTests.cpp


Index: unittests/clang-move/ClangMoveTests.cpp
===
--- unittests/clang-move/ClangMoveTests.cpp
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -391,6 +391,26 @@
   }
 }
 
+TEST(ClangMove, IgnoreMacroSymbolsAndMoveAll) {
+  const char TestCode[] = "#include \"foo.h\"";
+  std::vector TestHeaders = {
+"#define DEFINE_Foo int Foo = 1;\nDEFINE_Foo;\nclass Bar {};\n",
+"#define DEFINE(x) int var_##x = 1;\nDEFINE(foo);\nclass Bar {};\n",
+  };
+  move::MoveDefinitionSpec Spec;
+  Spec.Names.push_back("Bar");
+  Spec.OldHeader = "foo.h";
+  Spec.OldCC = "foo.cc";
+  Spec.NewHeader = "new_foo.h";
+  Spec.NewCC = "new_foo.cc";
+
+  for (const auto& Header : TestHeaders) {
+auto Results = runClangMoveOnCode(Spec, Header.c_str(), TestCode);
+EXPECT_EQ("", Results[Spec.OldHeader]);
+EXPECT_EQ(Header, Results[Spec.NewHeader]);
+  }
+}
+
 TEST(ClangMove, MacroInFunction) {
   const char TestHeader[] = "#define INT int\n"
 "class A {\npublic:\n  int f();\n};\n"
@@ -570,7 +590,9 @@
 "extern int kGlobalInt;\n"
 "extern const char* const kGlobalStr;\n"
 "} // namespace b\n"
-"} // namespace a\n";
+"} // namespace a\n"
+"#define DEFINE_FOO class Foo {};\n"
+"DEFINE_FOO\n";
   const char TestCode[] = "#include \"foo.h\"\n";
   move::MoveDefinitionSpec Spec;
   Spec.Names.push_back("B");
Index: clang-move/ClangMove.cpp
===
--- clang-move/ClangMove.cpp
+++ clang-move/ClangMove.cpp
@@ -523,6 +523,7 @@
   auto AllDeclsInHeader = namedDecl(
   unless(ForwardClassDecls), unless(namespaceDecl()),
   unless(usingDirectiveDecl()), // using namespace decl.
+  notInMacro(),
   InOldHeader,
   hasParent(decl(anyOf(namespaceDecl(), translationUnitDecl(,
   hasDeclContext(decl(anyOf(namespaceDecl(), translationUnitDecl();
@@ -905,10 +906,9 @@
 
   if (RemovedDecls.empty())
 return;
-  // Ignore symbols that are not supported (e.g. typedef and enum) when
-  // checking if there is unremoved symbol in old header. This makes sure that
-  // we always move old files to new files when all symbols produced from
-  // dump_decls are moved.
+  // Ignore symbols that are not supported when checking if there is unremoved
+  // symbol in old header. This makes sure that we always move old files to new
+  // files when all symbols produced from dump_decls are moved.
   auto IsSupportedKind = [](const clang::NamedDecl *Decl) {
 switch (Decl->getKind()) {
 case Decl::Kind::Function:


Index: unittests/clang-move/ClangMoveTests.cpp
===
--- unittests/clang-move/ClangMoveTests.cpp
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -391,6 +391,26 @@
   }
 }
 
+TEST(ClangMove, IgnoreMacroSymbolsAndMoveAll) {
+  const char TestCode[] = "#include \"foo.h\"";
+  std::vector TestHeaders = {
+"#define DEFINE_Foo int Foo = 1;\nDEFINE_Foo;\nclass Bar {};\n",
+"#define DEFINE(x) int var_##x = 1;\nDEFINE(foo);\nclass Bar {};\n",
+  };
+  move::MoveDefinitionSpec Spec;
+  Spec.Names.push_back("Bar");
+  Spec.OldHeader = "foo.h";
+  Spec.OldCC = "foo.cc";
+  Spec.NewHeader = "new_foo.h";
+  Spec.NewCC = "new_foo.cc";
+
+  for (const auto& Header : TestHeaders) {
+auto Results = runClangMoveOnCode(Spec, Header.c_str(), TestCode);
+EXPECT_EQ("", Results[Spec.OldHeader]);
+EXPECT_EQ(Header, Results[Spec.NewHeader]);
+  }
+}
+
 TEST(ClangMove, MacroInFunction) {
   const char TestHeader[] = "#define INT int\n"
 "class A {\npublic:\n  int f();\n};\n"
@@ -570,7 +590,9 @@
 "extern int kGlobalInt;\n"
 "extern const char* const kGlobalStr;\n"
 "} // namespace b\n"
-"} // namespace a\n";
+"} // namespace a\n"
+"#define DEFINE_FOO class Foo {};\n"
+"DEFINE_FOO\n";
   const char TestCode[] = "#include \"foo.h\"\n";
   move::MoveDefinitionSpec Spec;
   Spec.Names.push_back("B");
Index: clang-move/ClangMove.cpp
===
--- clang-move/ClangMove.cpp
+++ clang-move/ClangMove.cpp
@@ -523,6 +523,7 @@
   auto 

[PATCH] D43075: [clang-move] Don't dump macro symbols.

2018-02-09 Thread Haojian Wu via Phabricator via cfe-commits
hokein added inline comments.



Comment at: clang-move/ClangMove.cpp:526
   unless(usingDirectiveDecl()), // using namespace decl.
+  notInMacro(),
   InOldHeader,

ioeric wrote:
> I'd probably relax the condition a bit; theoretically tools would be able to 
> handle entire identifiers that are either spelled in macro or passed in by 
> users. But it's probably rare. Might worth a `FIXME` though?
This mainly affects the dump behavior. Moving symbols spelled in macro is 
tricky, and we can't guarantee always doing right thing. Actually, clang-move 
supports it partially. For the test case of this patch, if you move the `Foo` 
(names=`Foo`), clang-move will move the expansion macro (`DEFINE_Foo;`), 
although `Foo` is not dumped.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43075



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


[clang-tools-extra] r324742 - [clang-move] Don't dump macro symbols.

2018-02-09 Thread Haojian Wu via cfe-commits
Author: hokein
Date: Fri Feb  9 07:57:30 2018
New Revision: 324742

URL: http://llvm.org/viewvc/llvm-project?rev=324742=rev
Log:
[clang-move] Don't dump macro symbols.

Reviewers: ioeric

Subscribers: klimek, cfe-commits

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

Modified:
clang-tools-extra/trunk/clang-move/ClangMove.cpp
clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp

Modified: clang-tools-extra/trunk/clang-move/ClangMove.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-move/ClangMove.cpp?rev=324742=324741=324742=diff
==
--- clang-tools-extra/trunk/clang-move/ClangMove.cpp (original)
+++ clang-tools-extra/trunk/clang-move/ClangMove.cpp Fri Feb  9 07:57:30 2018
@@ -523,6 +523,7 @@ void ClangMoveTool::registerMatchers(ast
   auto AllDeclsInHeader = namedDecl(
   unless(ForwardClassDecls), unless(namespaceDecl()),
   unless(usingDirectiveDecl()), // using namespace decl.
+  notInMacro(),
   InOldHeader,
   hasParent(decl(anyOf(namespaceDecl(), translationUnitDecl(,
   hasDeclContext(decl(anyOf(namespaceDecl(), translationUnitDecl();
@@ -905,10 +906,9 @@ void ClangMoveTool::onEndOfTranslationUn
 
   if (RemovedDecls.empty())
 return;
-  // Ignore symbols that are not supported (e.g. typedef and enum) when
-  // checking if there is unremoved symbol in old header. This makes sure that
-  // we always move old files to new files when all symbols produced from
-  // dump_decls are moved.
+  // Ignore symbols that are not supported when checking if there is unremoved
+  // symbol in old header. This makes sure that we always move old files to new
+  // files when all symbols produced from dump_decls are moved.
   auto IsSupportedKind = [](const clang::NamedDecl *Decl) {
 switch (Decl->getKind()) {
 case Decl::Kind::Function:

Modified: clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp?rev=324742=324741=324742=diff
==
--- clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp Fri Feb  9 
07:57:30 2018
@@ -391,6 +391,26 @@ TEST(ClangMove, DontMoveAll) {
   }
 }
 
+TEST(ClangMove, IgnoreMacroSymbolsAndMoveAll) {
+  const char TestCode[] = "#include \"foo.h\"";
+  std::vector TestHeaders = {
+"#define DEFINE_Foo int Foo = 1;\nDEFINE_Foo;\nclass Bar {};\n",
+"#define DEFINE(x) int var_##x = 1;\nDEFINE(foo);\nclass Bar {};\n",
+  };
+  move::MoveDefinitionSpec Spec;
+  Spec.Names.push_back("Bar");
+  Spec.OldHeader = "foo.h";
+  Spec.OldCC = "foo.cc";
+  Spec.NewHeader = "new_foo.h";
+  Spec.NewCC = "new_foo.cc";
+
+  for (const auto& Header : TestHeaders) {
+auto Results = runClangMoveOnCode(Spec, Header.c_str(), TestCode);
+EXPECT_EQ("", Results[Spec.OldHeader]);
+EXPECT_EQ(Header, Results[Spec.NewHeader]);
+  }
+}
+
 TEST(ClangMove, MacroInFunction) {
   const char TestHeader[] = "#define INT int\n"
 "class A {\npublic:\n  int f();\n};\n"
@@ -570,7 +590,9 @@ TEST(ClangMove, DumpDecls) {
 "extern int kGlobalInt;\n"
 "extern const char* const kGlobalStr;\n"
 "} // namespace b\n"
-"} // namespace a\n";
+"} // namespace a\n"
+"#define DEFINE_FOO class Foo {};\n"
+"DEFINE_FOO\n";
   const char TestCode[] = "#include \"foo.h\"\n";
   move::MoveDefinitionSpec Spec;
   Spec.Names.push_back("B");


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


[PATCH] D43075: [clang-move] Don't dump macro symbols.

2018-02-09 Thread Haojian Wu via Phabricator via cfe-commits
hokein updated this revision to Diff 133621.
hokein marked an inline comment as done.
hokein added a comment.

Add more tests.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43075

Files:
  clang-move/ClangMove.cpp
  unittests/clang-move/ClangMoveTests.cpp


Index: unittests/clang-move/ClangMoveTests.cpp
===
--- unittests/clang-move/ClangMoveTests.cpp
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -391,6 +391,26 @@
   }
 }
 
+TEST(ClangMove, IgnoreMacroSymbolsAndMoveAll) {
+  const char TestCode[] = "#include \"foo.h\"";
+  std::vector TestHeaders = {
+"#define DEFINE_Foo int Foo = 1;\nDEFINE_Foo;\nclass Bar {};\n",
+"#define DEFINE(x) int var_##x = 1;\nDEFINE(foo);\nclass Bar {};\n",
+  };
+  move::MoveDefinitionSpec Spec;
+  Spec.Names.push_back("Bar");
+  Spec.OldHeader = "foo.h";
+  Spec.OldCC = "foo.cc";
+  Spec.NewHeader = "new_foo.h";
+  Spec.NewCC = "new_foo.cc";
+
+  for (const auto& Header : TestHeaders) {
+auto Results = runClangMoveOnCode(Spec, Header.c_str(), TestCode);
+EXPECT_EQ("", Results[Spec.OldHeader]);
+EXPECT_EQ(Header, Results[Spec.NewHeader]);
+  }
+}
+
 TEST(ClangMove, MacroInFunction) {
   const char TestHeader[] = "#define INT int\n"
 "class A {\npublic:\n  int f();\n};\n"
@@ -570,7 +590,9 @@
 "extern int kGlobalInt;\n"
 "extern const char* const kGlobalStr;\n"
 "} // namespace b\n"
-"} // namespace a\n";
+"} // namespace a\n"
+"#define DEFINE_FOO class Foo {};\n"
+"DEFINE_FOO\n";
   const char TestCode[] = "#include \"foo.h\"\n";
   move::MoveDefinitionSpec Spec;
   Spec.Names.push_back("B");
Index: clang-move/ClangMove.cpp
===
--- clang-move/ClangMove.cpp
+++ clang-move/ClangMove.cpp
@@ -523,6 +523,7 @@
   auto AllDeclsInHeader = namedDecl(
   unless(ForwardClassDecls), unless(namespaceDecl()),
   unless(usingDirectiveDecl()), // using namespace decl.
+  notInMacro(),
   InOldHeader,
   hasParent(decl(anyOf(namespaceDecl(), translationUnitDecl(,
   hasDeclContext(decl(anyOf(namespaceDecl(), translationUnitDecl();
@@ -905,10 +906,9 @@
 
   if (RemovedDecls.empty())
 return;
-  // Ignore symbols that are not supported (e.g. typedef and enum) when
-  // checking if there is unremoved symbol in old header. This makes sure that
-  // we always move old files to new files when all symbols produced from
-  // dump_decls are moved.
+  // Ignore symbols that are not supported when checking if there is unremoved
+  // symbol in old header. This makes sure that we always move old files to new
+  // files when all symbols produced from dump_decls are moved.
   auto IsSupportedKind = [](const clang::NamedDecl *Decl) {
 switch (Decl->getKind()) {
 case Decl::Kind::Function:


Index: unittests/clang-move/ClangMoveTests.cpp
===
--- unittests/clang-move/ClangMoveTests.cpp
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -391,6 +391,26 @@
   }
 }
 
+TEST(ClangMove, IgnoreMacroSymbolsAndMoveAll) {
+  const char TestCode[] = "#include \"foo.h\"";
+  std::vector TestHeaders = {
+"#define DEFINE_Foo int Foo = 1;\nDEFINE_Foo;\nclass Bar {};\n",
+"#define DEFINE(x) int var_##x = 1;\nDEFINE(foo);\nclass Bar {};\n",
+  };
+  move::MoveDefinitionSpec Spec;
+  Spec.Names.push_back("Bar");
+  Spec.OldHeader = "foo.h";
+  Spec.OldCC = "foo.cc";
+  Spec.NewHeader = "new_foo.h";
+  Spec.NewCC = "new_foo.cc";
+
+  for (const auto& Header : TestHeaders) {
+auto Results = runClangMoveOnCode(Spec, Header.c_str(), TestCode);
+EXPECT_EQ("", Results[Spec.OldHeader]);
+EXPECT_EQ(Header, Results[Spec.NewHeader]);
+  }
+}
+
 TEST(ClangMove, MacroInFunction) {
   const char TestHeader[] = "#define INT int\n"
 "class A {\npublic:\n  int f();\n};\n"
@@ -570,7 +590,9 @@
 "extern int kGlobalInt;\n"
 "extern const char* const kGlobalStr;\n"
 "} // namespace b\n"
-"} // namespace a\n";
+"} // namespace a\n"
+"#define DEFINE_FOO class Foo {};\n"
+"DEFINE_FOO\n";
   const char TestCode[] = "#include \"foo.h\"\n";
   move::MoveDefinitionSpec Spec;
   Spec.Names.push_back("B");
Index: clang-move/ClangMove.cpp
===
--- clang-move/ClangMove.cpp
+++ clang-move/ClangMove.cpp
@@ -523,6 +523,7 @@
   auto AllDeclsInHeader = namedDecl(
   unless(ForwardClassDecls), unless(namespaceDecl()),
   unless(usingDirectiveDecl()), // using namespace 

[PATCH] D43114: clang-format: fix formatting of ObjC @synchronized blocks

2018-02-09 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton added inline comments.



Comment at: lib/Format/UnwrappedLineParser.cpp:1130
+if (FormatTok->Tok.is(tok::l_brace)) {
+  if (Style.BraceWrapping.AfterObjCDeclaration)
+addUnwrappedLine();

Typz wrote:
> Wondering if formatting with this style is appropriate: the clang-format doc 
> points in that direction, but it seems to me both `@synchronized` and 
> `@autoreleasepool` are more akin to "control statements".
> 
> For consistency (esp. in ObjC++ code), as a user, I would tend to have these 
> blocks indented like control statements while interfaces/implementations 
> blocks would be indented like classes/structs.
> 
> So maybe it would be better to introduce a new BraceWrapping style 
> 'AfterObjCSpecialBlock` to control these cases, matching the possibilities 
> that are given for control statements vs classes. What do you think?
Hmm, I definitely agree with that logic. I don't see them acting as 
declarations in any way, they are definitely like control statements.



Repository:
  rC Clang

https://reviews.llvm.org/D43114



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


[PATCH] D43121: clang-format: keep ObjC colon alignment with short object name

2018-02-09 Thread Francois Ferrand via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC324741: clang-format: keep ObjC colon alignment with short 
object name (authored by Typz, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D43121?vs=133619=133620#toc

Repository:
  rC Clang

https://reviews.llvm.org/D43121

Files:
  lib/Format/ContinuationIndenter.cpp
  lib/Format/TokenAnnotator.cpp
  unittests/Format/FormatTestObjC.cpp


Index: unittests/Format/FormatTestObjC.cpp
===
--- unittests/Format/FormatTestObjC.cpp
+++ unittests/Format/FormatTestObjC.cpp
@@ -693,8 +693,8 @@
   // Formats pair-parameters.
   verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
   verifyFormat("[I drawRectOn:surface //\n"
-   "ofSize:aa:bbb\n"
-   "  atOrigin:cc:dd];");
+   "   ofSize:aa:bbb\n"
+   " atOrigin:cc:dd];");
 
   // Inline block as a first argument.
   verifyFormat("[object justBlock:^{\n"
@@ -760,6 +760,26 @@
   "  backing:NSBackingStoreBuffered\n"
   "defer:NO]);\n"
   "}");
+
+  // Respect continuation indent and colon alignment (e.g. when object name is
+  // short, and first selector is the longest one)
+  Style = getLLVMStyle();
+  Style.Language = FormatStyle::LK_ObjC;
+  Style.ContinuationIndentWidth = 8;
+  verifyFormat("[self performSelectorOnMainThread:@selector(loadAccessories)\n"
+   "   withObject:nil\n"
+   "waitUntilDone:false];");
+  verifyFormat("[self performSelector:@selector(loadAccessories)\n"
+   "withObjectOnMainThread:nil\n"
+   " waitUntilDone:false];");
+  verifyFormat("[a\n"
+   "
performSelectorOnMainThread:@selector(loadAccessories)\n"
+   " withObject:nil\n"
+   "  waitUntilDone:false];");
+  verifyFormat("[self // force wrapping\n"
+   "
performSelectorOnMainThread:@selector(loadAccessories)\n"
+   " withObject:nil\n"
+   "  waitUntilDone:false];");
 }
 
 TEST_F(FormatTestObjC, ObjCAt) {
Index: lib/Format/TokenAnnotator.cpp
===
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -591,12 +591,12 @@
 BeforePrevious->is(tok::r_square) ||
 Contexts.back().LongestObjCSelectorName == 0) {
   Tok->Previous->Type = TT_SelectorName;
-  if (Tok->Previous->ColumnWidth >
-  Contexts.back().LongestObjCSelectorName)
-Contexts.back().LongestObjCSelectorName =
-Tok->Previous->ColumnWidth;
   if (!Contexts.back().FirstObjCSelectorName)
 Contexts.back().FirstObjCSelectorName = Tok->Previous;
+  else if (Tok->Previous->ColumnWidth >
+   Contexts.back().LongestObjCSelectorName)
+Contexts.back().LongestObjCSelectorName =
+Tok->Previous->ColumnWidth;
 }
   } else if (Contexts.back().ColonIsForRangeExpr) {
 Tok->Type = TT_RangeBasedForLoopColon;
Index: lib/Format/ContinuationIndenter.cpp
===
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -701,7 +701,8 @@
  ? std::max(State.Stack.back().Indent,
 State.FirstIndent + Style.ContinuationIndentWidth)
  : State.Stack.back().Indent) +
-NextNonComment->LongestObjCSelectorName;
+std::max(NextNonComment->LongestObjCSelectorName,
+ NextNonComment->ColumnWidth);
   }
 } else if (State.Stack.back().AlignColons &&
State.Stack.back().ColonPos <= NextNonComment->ColumnWidth) {
@@ -900,7 +901,8 @@
   ? std::max(State.Stack.back().Indent,
  State.FirstIndent + Style.ContinuationIndentWidth)
   : State.Stack.back().Indent) +
- NextNonComment->LongestObjCSelectorName -
+ std::max(NextNonComment->LongestObjCSelectorName,
+  NextNonComment->ColumnWidth) -
  NextNonComment->ColumnWidth;
 }
 if (!State.Stack.back().AlignColons)


Index: unittests/Format/FormatTestObjC.cpp
===
--- unittests/Format/FormatTestObjC.cpp
+++ unittests/Format/FormatTestObjC.cpp
@@ -693,8 +693,8 @@
   // Formats pair-parameters.
   verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
   verifyFormat("[I drawRectOn:surface //\n"
-   "ofSize:aa:bbb\n"
-   "  

[PATCH] D43124: [clang-format] Improve ObjC headers detection

2018-02-09 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton accepted this revision.
benhamilton added a comment.
This revision is now accepted and ready to land.

testcase 



Repository:
  rC Clang

https://reviews.llvm.org/D43124



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


r324741 - clang-format: keep ObjC colon alignment with short object name

2018-02-09 Thread Francois Ferrand via cfe-commits
Author: typz
Date: Fri Feb  9 07:41:56 2018
New Revision: 324741

URL: http://llvm.org/viewvc/llvm-project?rev=324741=rev
Log:
clang-format: keep ObjC colon alignment with short object name

Summary:
When the target object expression is short and the first selector name
is long, clang-format used to break the colon alignment:

  [I performSelectorOnMainThread:@selector(loadAccessories)
   withObject:nil
waitUntilDone:false];

This happens because the colon is placed at `ContinuationIndent +
LongestObjCSelectorName`, so that any selector can be wrapped. This is
however not needed in case the longest selector is the firstone, and
not wrapped.

To overcome this, this patch does not include the first selector in
`LongestObjCSelectorName` computation (in TokenAnnotator), and lets
`ContinuationIndenter` decide how to account for the first selector
when wrapping. (Note this was already partly the case, see line 521
of ContinuationIndenter.cpp)

This way, the code gets properly aligned whenever possible without
breaking the continuation indent.

  [I performSelectorOnMainThread:@selector(loadAccessories)
  withObject:nil
   waitUntilDone:false];
  [I // force break
  performSelectorOnMainThread:@selector(loadAccessories)
   withObject:nil
waitUntilDone:false];
  [I perform:@selector(loadAccessories)
  withSelectorOnMainThread:true
 waitUntilDone:false];

Reviewers: krasimir, djasper, klimek

Subscribers: cfe-commits

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

Modified:
cfe/trunk/lib/Format/ContinuationIndenter.cpp
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/unittests/Format/FormatTestObjC.cpp

Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=324741=324740=324741=diff
==
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Fri Feb  9 07:41:56 2018
@@ -701,7 +701,8 @@ unsigned ContinuationIndenter::addTokenO
  ? std::max(State.Stack.back().Indent,
 State.FirstIndent + Style.ContinuationIndentWidth)
  : State.Stack.back().Indent) +
-NextNonComment->LongestObjCSelectorName;
+std::max(NextNonComment->LongestObjCSelectorName,
+ NextNonComment->ColumnWidth);
   }
 } else if (State.Stack.back().AlignColons &&
State.Stack.back().ColonPos <= NextNonComment->ColumnWidth) {
@@ -900,7 +901,8 @@ unsigned ContinuationIndenter::getNewLin
   ? std::max(State.Stack.back().Indent,
  State.FirstIndent + Style.ContinuationIndentWidth)
   : State.Stack.back().Indent) +
- NextNonComment->LongestObjCSelectorName -
+ std::max(NextNonComment->LongestObjCSelectorName,
+  NextNonComment->ColumnWidth) -
  NextNonComment->ColumnWidth;
 }
 if (!State.Stack.back().AlignColons)

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=324741=324740=324741=diff
==
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Fri Feb  9 07:41:56 2018
@@ -591,12 +591,12 @@ private:
 BeforePrevious->is(tok::r_square) ||
 Contexts.back().LongestObjCSelectorName == 0) {
   Tok->Previous->Type = TT_SelectorName;
-  if (Tok->Previous->ColumnWidth >
-  Contexts.back().LongestObjCSelectorName)
-Contexts.back().LongestObjCSelectorName =
-Tok->Previous->ColumnWidth;
   if (!Contexts.back().FirstObjCSelectorName)
 Contexts.back().FirstObjCSelectorName = Tok->Previous;
+  else if (Tok->Previous->ColumnWidth >
+   Contexts.back().LongestObjCSelectorName)
+Contexts.back().LongestObjCSelectorName =
+Tok->Previous->ColumnWidth;
 }
   } else if (Contexts.back().ColonIsForRangeExpr) {
 Tok->Type = TT_RangeBasedForLoopColon;

Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=324741=324740=324741=diff
==
--- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Fri Feb  9 07:41:56 2018
@@ -693,8 +693,8 @@ TEST_F(FormatTestObjC, FormatObjCMethodE
   // Formats pair-parameters.
   verifyFormat("[I drawRectOn:surface ofSize:aa:bbb 

[PATCH] D43121: clang-format: keep ObjC colon alignment with short object name

2018-02-09 Thread Francois Ferrand via Phabricator via cfe-commits
Typz updated this revision to Diff 133619.
Typz added a comment.

rebase on latest master.


Repository:
  rC Clang

https://reviews.llvm.org/D43121

Files:
  lib/Format/ContinuationIndenter.cpp
  lib/Format/TokenAnnotator.cpp
  unittests/Format/FormatTestObjC.cpp


Index: unittests/Format/FormatTestObjC.cpp
===
--- unittests/Format/FormatTestObjC.cpp
+++ unittests/Format/FormatTestObjC.cpp
@@ -693,8 +693,8 @@
   // Formats pair-parameters.
   verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
   verifyFormat("[I drawRectOn:surface //\n"
-   "ofSize:aa:bbb\n"
-   "  atOrigin:cc:dd];");
+   "   ofSize:aa:bbb\n"
+   " atOrigin:cc:dd];");
 
   // Inline block as a first argument.
   verifyFormat("[object justBlock:^{\n"
@@ -760,6 +760,26 @@
   "  backing:NSBackingStoreBuffered\n"
   "defer:NO]);\n"
   "}");
+
+  // Respect continuation indent and colon alignment (e.g. when object name is
+  // short, and first selector is the longest one)
+  Style = getLLVMStyle();
+  Style.Language = FormatStyle::LK_ObjC;
+  Style.ContinuationIndentWidth = 8;
+  verifyFormat("[self performSelectorOnMainThread:@selector(loadAccessories)\n"
+   "   withObject:nil\n"
+   "waitUntilDone:false];");
+  verifyFormat("[self performSelector:@selector(loadAccessories)\n"
+   "withObjectOnMainThread:nil\n"
+   " waitUntilDone:false];");
+  verifyFormat("[a\n"
+   "
performSelectorOnMainThread:@selector(loadAccessories)\n"
+   " withObject:nil\n"
+   "  waitUntilDone:false];");
+  verifyFormat("[self // force wrapping\n"
+   "
performSelectorOnMainThread:@selector(loadAccessories)\n"
+   " withObject:nil\n"
+   "  waitUntilDone:false];");
 }
 
 TEST_F(FormatTestObjC, ObjCAt) {
Index: lib/Format/TokenAnnotator.cpp
===
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -591,12 +591,12 @@
 BeforePrevious->is(tok::r_square) ||
 Contexts.back().LongestObjCSelectorName == 0) {
   Tok->Previous->Type = TT_SelectorName;
-  if (Tok->Previous->ColumnWidth >
-  Contexts.back().LongestObjCSelectorName)
-Contexts.back().LongestObjCSelectorName =
-Tok->Previous->ColumnWidth;
   if (!Contexts.back().FirstObjCSelectorName)
 Contexts.back().FirstObjCSelectorName = Tok->Previous;
+  else if (Tok->Previous->ColumnWidth >
+   Contexts.back().LongestObjCSelectorName)
+Contexts.back().LongestObjCSelectorName =
+Tok->Previous->ColumnWidth;
 }
   } else if (Contexts.back().ColonIsForRangeExpr) {
 Tok->Type = TT_RangeBasedForLoopColon;
Index: lib/Format/ContinuationIndenter.cpp
===
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -701,7 +701,8 @@
  ? std::max(State.Stack.back().Indent,
 State.FirstIndent + Style.ContinuationIndentWidth)
  : State.Stack.back().Indent) +
-NextNonComment->LongestObjCSelectorName;
+std::max(NextNonComment->LongestObjCSelectorName,
+ NextNonComment->ColumnWidth);
   }
 } else if (State.Stack.back().AlignColons &&
State.Stack.back().ColonPos <= NextNonComment->ColumnWidth) {
@@ -900,7 +901,8 @@
   ? std::max(State.Stack.back().Indent,
  State.FirstIndent + Style.ContinuationIndentWidth)
   : State.Stack.back().Indent) +
- NextNonComment->LongestObjCSelectorName -
+ std::max(NextNonComment->LongestObjCSelectorName,
+  NextNonComment->ColumnWidth) -
  NextNonComment->ColumnWidth;
 }
 if (!State.Stack.back().AlignColons)


Index: unittests/Format/FormatTestObjC.cpp
===
--- unittests/Format/FormatTestObjC.cpp
+++ unittests/Format/FormatTestObjC.cpp
@@ -693,8 +693,8 @@
   // Formats pair-parameters.
   verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
   verifyFormat("[I drawRectOn:surface //\n"
-   "ofSize:aa:bbb\n"
-   "  atOrigin:cc:dd];");
+   "   ofSize:aa:bbb\n"
+   " atOrigin:cc:dd];");
 
   // Inline block as a first argument.
   verifyFormat("[object justBlock:^{\n"
@@ -760,6 +760,26 

[PATCH] D43120: [clang-tidy] New checker for exceptions that are created but not thrown

2018-02-09 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

One concern I have is with RAII objects with "exception" in the name. You may 
already properly handle this, but I'd like to see a test case like:

  struct ExceptionRAII {
ExceptionRAII() {}
~ExceptionRAII() {}
  };
  
  void foo() {
ExceptionRAII E; // Don't trigger on this
  }




Comment at: clang-tidy/misc/ThrowKeywordMissingCheck.cpp:45
+  diag(TemporaryExpr->getLocStart(),
+   "exception instantiated but not bound (did you intend to 'throw'?)");
+}

I'm not keen on the wording here ("bound" isn't a common phrase for 
exceptions). How about `"suspicious exception object created but not thrown; 
did you mean 'throw %0'"` and then pass in the text for the object construction?



Comment at: docs/clang-tidy/checks/misc-throw-keyword-missing.rst:6
+
+This check warns about the potentially missing `throw` keyword. If a temporary 
object is created,
+but the object's type derives from (or the same as) a class that has 
'EXCEPTION', 'Exception' or

about the potentially -> about a potentially



Comment at: docs/clang-tidy/checks/misc-throw-keyword-missing.rst:7
+This check warns about the potentially missing `throw` keyword. If a temporary 
object is created,
+but the object's type derives from (or the same as) a class that has 
'EXCEPTION', 'Exception' or
+'exception' in its name, we can assume that the programmer's intention was to 
throw that object.

or the same as -> or is the same as



Comment at: docs/clang-tidy/checks/misc-throw-keyword-missing.rst:14
+  void f(int i) {
+if(i < 0) {
+  // Exception is created but is not thrown

Can you format the code snippet?


https://reviews.llvm.org/D43120



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


[PATCH] D35894: [clangd] Code hover for Clangd

2018-02-09 Thread Simon Marchi via Phabricator via cfe-commits
simark added a comment.

In https://reviews.llvm.org/D35894#1003342, @simark wrote:

> The only problem I see is that when hovering a function/struct name, it now 
> prints the whole function/struct definition.  When talking with @malaperle, 
> he told me that you had discussed it before and we should not have the 
> definition in the hover, just the prototype for a function and the name (e.g. 
> "struct foo") for a struct.  Glancing quickly at the PrintingPolicy, I don't 
> see a way to do that.  Do you have any idea?


Arrg, Sorry, I just re-read your comment and saw that you used TerseOutput 
which does that.  I did not catch that when transcribing the code (I did not 
want to copy paste to understand the code better, but got bitten).


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894



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


[PATCH] D42840: [docs] Fix duplicate arguments for JoinedAndSeparate

2018-02-09 Thread Jonas Hahnfeld via Phabricator via cfe-commits
Hahnfeld added a comment.

Ping


Repository:
  rC Clang

https://reviews.llvm.org/D42840



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


[PATCH] D42640: [clangd] collect symbol #include & insert #include in global code completion.

2018-02-09 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

Insertion side LGTM, feel free to split and land.
Sorry I need to take off and will need to get to indexing on monday :(




Comment at: clangd/ClangdServer.cpp:368
 
+/// Calculates the shortest possible include path when inserting \p Header to 
\p
+/// File, by matching \p Header against all include search directories for \p

ioeric wrote:
> sammccall wrote:
> > This has a fair amount of logic (well, plumbing :-D) and uses relatively 
> > little from ClangdServer.
> > Can we move `shortenIncludePath` to a separate file and pass in the FS and 
> > command?
> > 
> > I'd suggest maybe `Headers.h` - The formatting part of `insertInclude` 
> > could also fit there, as well as probably the logic from 
> > `switchSourceHeader` I think (the latter not in this patch of course).
> > 
> > This won't really help much with testing, I just find it gets hard to 
> > navigate files that have lots of details of unrelated features. ClangdUnit 
> > and ClangdServer both have this potential to grow without bound, though 
> > they're in reasonable shape now. Interested what you think!
> Done.
> 
> I didn't move the formatting code, as half of the code is pulling out the 
> style, which we might want to share/change depending on other clangd logics 
> that might use style.
I'd still think pulling out `Expected insertInclude(File, 
Code, Header, VFS, Style)` would be worthwhile here - the formatting isn't a 
lot of code, but it's a bit magic, plus the quote handling... it's a bit of 
code. It'd make it more obvious what the interactions with ClangdServer's state 
are. But up to you, we can always do this later.



Comment at: clangd/ClangdServer.cpp:370
+/// File, by matching \p Header against all include search directories for \p
+/// File via `clang::HeaderSearch`.
+///

sammccall wrote:
> maybe drop "via clang::HeaderSearch" (it's doc'd in the implementation) and 
> add an example?
> 
> It might be worth explicitly stating that the result is an #include string 
> (with quotes) - you just call it a "path" here.
> 
> "shortest" makes sense as a first implementation, but we may want to document 
> something more like "best" - I know there are codebases we care about where 
> file-relative paths are banned. Also I suspect we don't give 
> "../../../../Foo.h" even if it's shortest :-)
> "shortest" makes sense as a first implementation, but we may want to document 
> something more like "best" - I know there are codebases we care about where 
> file-relative paths are banned. Also I suspect we don't give 
> "../../../../Foo.h" even if it's shortest :-)

I think this part wasn't addressed



Comment at: clangd/Headers.cpp:74
+
+  // We don't need to provide the content of \p File, as we are only interested
+  // in the include search directories in the compile command.

comment is outdated now



Comment at: clangd/Headers.cpp:114
+
+  log("Suggested #include is: " + Suggested);
+  return Suggested;

can you include the Header in this log message? (and possibly File, but that 
might add more noise than signal)



Comment at: clangd/Headers.h:30
+/// \return A quoted "path" or . If \p Header is already (directly)
+/// included in the file (including those included via different paths), an
+/// error will be returned.

header-already-included is not an error condition.

Suggest returning llvm::Expected, or returning "" for this 
case.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42640



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


[clang-tools-extra] r324736 - [clangd] Fix crash in tests in debug mode.

2018-02-09 Thread Ilya Biryukov via cfe-commits
Author: ibiryukov
Date: Fri Feb  9 07:11:07 2018
New Revision: 324736

URL: http://llvm.org/viewvc/llvm-project?rev=324736=rev
Log:
[clangd] Fix crash in tests in debug mode.

Caused by the lack of checking of an Expected value in the previous
commit.

Modified:
clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp

Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=324736=324735=324736=diff
==
--- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Fri Feb  9 
07:11:07 2018
@@ -483,9 +483,9 @@ TEST_F(ClangdVFSTest, InvalidCompileComm
   .get()
   .Value.items,
   IsEmpty());
-  EXPECT_THAT(
-  Server.signatureHelp(FooCpp, Position{0, 0}).get().Value.signatures,
-  IsEmpty());
+  auto SigHelp = Server.signatureHelp(FooCpp, Position{0, 0});
+  ASSERT_TRUE(bool(SigHelp)) << "signatureHelp returned an error";
+  EXPECT_THAT(SigHelp->Value.signatures, IsEmpty());
 }
 
 class ClangdThreadingTest : public ClangdVFSTest {};


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


[PATCH] D35894: [clangd] Code hover for Clangd

2018-02-09 Thread Simon Marchi via Phabricator via cfe-commits
simark added a comment.

The only problem I see is that when hovering a function name, it now prints the 
whole function definition.  When talking with @malaperle, he told me that you 
had discussed it before and we should not have the definition in the hover, 
just the prototype.  Glancing quickly at the PrintingPolicy, I don't see a way 
to just print the prototype of the function.  Do you have any idea?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894



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


  1   2   >