[PATCH] D53780: Fix bitcast to address space cast for coerced load/stores

2018-10-28 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: lib/CodeGen/CGCall.cpp:1260
   llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize),
   false);
   return CGF.Builder.CreateLoad(Tmp);

The main reason why `llvm.memcpy` is an overloaded intrinsic is so that you can 
copy things in arbitrary address spaces.  Please just cast to the appropriate 
`i8` pointer type in the corresponding address spaces.


Repository:
  rC Clang

https://reviews.llvm.org/D53780



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


r345487 - Revert "Support for groups of attributes in #pragma clang attribute"

2018-10-28 Thread Erik Pilkington via cfe-commits
Author: epilk
Date: Sun Oct 28 20:24:16 2018
New Revision: 345487

URL: http://llvm.org/viewvc/llvm-project?rev=345487=rev
Log:
Revert "Support for groups of attributes in #pragma clang attribute"

This reverts commit r345486.

Looks like it causes some old versions of GCC to crash, I'll see if I can
work around it and recommit...

Modified:
cfe/trunk/docs/LanguageExtensions.rst
cfe/trunk/docs/ReleaseNotes.rst
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParsePragma.cpp
cfe/trunk/lib/Sema/SemaAttr.cpp
cfe/trunk/test/Parser/pragma-attribute.cpp
cfe/trunk/test/Sema/pragma-attribute.c

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=345487=345486=345487=diff
==
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Sun Oct 28 20:24:16 2018
@@ -2651,19 +2651,17 @@ Specifying an attribute for multiple dec
 
 The ``#pragma clang attribute`` directive can be used to apply an attribute to
 multiple declarations. The ``#pragma clang attribute push`` variation of the
-directive pushes a new "scope" of ``#pragma clang attribute`` that attributes
-can be added to. The ``#pragma clang attribute (...)`` variation adds an
-attribute to that scope, and the ``#pragma clang attribute pop`` variation pops
-the scope. You can also use ``#pragma clang attribute push (...)``, which is a
-shorthand for when you want to add one attribute to a new scope. Multiple push
-directives can be nested inside each other.
+directive pushes a new attribute to the attribute stack. The declarations that
+follow the pragma receive the attributes that are on the attribute stack, until
+the stack is cleared using a ``#pragma clang attribute pop`` directive. 
Multiple
+push directives can be nested inside each other.
 
 The attributes that are used in the ``#pragma clang attribute`` directives
 can be written using the GNU-style syntax:
 
 .. code-block:: c++
 
-  #pragma clang attribute push (__attribute__((annotate("custom"))), apply_to 
= function)
+  #pragma clang attribute push(__attribute__((annotate("custom"))), apply_to = 
function)
 
   void function(); // The function now has the annotate("custom") attribute
 
@@ -2673,7 +2671,7 @@ The attributes can also be written using
 
 .. code-block:: c++
 
-  #pragma clang attribute push ([[noreturn]], apply_to = function)
+  #pragma clang attribute push([[noreturn]], apply_to = function)
 
   void function(); // The function now has the [[noreturn]] attribute
 
@@ -2683,7 +2681,7 @@ The ``__declspec`` style syntax is also
 
 .. code-block:: c++
 
-  #pragma clang attribute push (__declspec(dllexport), apply_to = function)
+  #pragma clang attribute push(__declspec(dllexport), apply_to = function)
 
   void function(); // The function now has the __declspec(dllexport) attribute
 

Modified: cfe/trunk/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=345487=345486=345487=diff
==
--- cfe/trunk/docs/ReleaseNotes.rst (original)
+++ cfe/trunk/docs/ReleaseNotes.rst Sun Oct 28 20:24:16 2018
@@ -86,8 +86,8 @@ Modified Compiler Flags
 New Pragmas in Clang
 
 
-- Clang now supports adding multiple ``#pragma clang attribute`` attributes 
into
-  a "scope" of ``push``ed attributes.
+Clang now supports the ...
+
 
 Attribute Changes in Clang
 --

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=345487=345486=345487=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sun Oct 28 20:24:16 
2018
@@ -1032,8 +1032,8 @@ def err_pragma_optimize_invalid_argument
 def err_pragma_optimize_extra_argument : Error<
   "unexpected extra argument '%0' to '#pragma clang optimize'">;
 // - #pragma clang attribute
-def err_pragma_attribute_expected_push_pop_paren : Error<
-  "expected 'push', 'pop', or '(' after '#pragma clang attribute'">;
+def err_pragma_attribute_expected_push_pop : Error<
+  "expected 'push' or 'pop' after '#pragma clang attribute'">;
 def err_pragma_attribute_invalid_argument : Error<
   "unexpected argument '%0' to '#pragma clang attribute'; "
   "expected 'push' or 'pop'">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=345487=345486=345487=diff

[PATCH] D53621: Support for groups of attributes in #pragma clang attribute

2018-10-28 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL345486: Support for groups of attributes in #pragma clang 
attribute (authored by epilk, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D53621?vs=171218=171447#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D53621

Files:
  cfe/trunk/docs/LanguageExtensions.rst
  cfe/trunk/docs/ReleaseNotes.rst
  cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/Parse/ParsePragma.cpp
  cfe/trunk/lib/Sema/SemaAttr.cpp
  cfe/trunk/test/Parser/pragma-attribute.cpp
  cfe/trunk/test/Sema/pragma-attribute.c

Index: cfe/trunk/docs/LanguageExtensions.rst
===
--- cfe/trunk/docs/LanguageExtensions.rst
+++ cfe/trunk/docs/LanguageExtensions.rst
@@ -2651,17 +2651,19 @@
 
 The ``#pragma clang attribute`` directive can be used to apply an attribute to
 multiple declarations. The ``#pragma clang attribute push`` variation of the
-directive pushes a new attribute to the attribute stack. The declarations that
-follow the pragma receive the attributes that are on the attribute stack, until
-the stack is cleared using a ``#pragma clang attribute pop`` directive. Multiple
-push directives can be nested inside each other.
+directive pushes a new "scope" of ``#pragma clang attribute`` that attributes
+can be added to. The ``#pragma clang attribute (...)`` variation adds an
+attribute to that scope, and the ``#pragma clang attribute pop`` variation pops
+the scope. You can also use ``#pragma clang attribute push (...)``, which is a
+shorthand for when you want to add one attribute to a new scope. Multiple push
+directives can be nested inside each other.
 
 The attributes that are used in the ``#pragma clang attribute`` directives
 can be written using the GNU-style syntax:
 
 .. code-block:: c++
 
-  #pragma clang attribute push(__attribute__((annotate("custom"))), apply_to = function)
+  #pragma clang attribute push (__attribute__((annotate("custom"))), apply_to = function)
 
   void function(); // The function now has the annotate("custom") attribute
 
@@ -2671,7 +2673,7 @@
 
 .. code-block:: c++
 
-  #pragma clang attribute push([[noreturn]], apply_to = function)
+  #pragma clang attribute push ([[noreturn]], apply_to = function)
 
   void function(); // The function now has the [[noreturn]] attribute
 
@@ -2681,7 +2683,7 @@
 
 .. code-block:: c++
 
-  #pragma clang attribute push(__declspec(dllexport), apply_to = function)
+  #pragma clang attribute push (__declspec(dllexport), apply_to = function)
 
   void function(); // The function now has the __declspec(dllexport) attribute
 
Index: cfe/trunk/docs/ReleaseNotes.rst
===
--- cfe/trunk/docs/ReleaseNotes.rst
+++ cfe/trunk/docs/ReleaseNotes.rst
@@ -86,8 +86,8 @@
 New Pragmas in Clang
 
 
-Clang now supports the ...
-
+- Clang now supports adding multiple ``#pragma clang attribute`` attributes into
+  a "scope" of ``push``ed attributes.
 
 Attribute Changes in Clang
 --
Index: cfe/trunk/include/clang/Sema/Sema.h
===
--- cfe/trunk/include/clang/Sema/Sema.h
+++ cfe/trunk/include/clang/Sema/Sema.h
@@ -491,15 +491,22 @@
   /// VisContext - Manages the stack for \#pragma GCC visibility.
   void *VisContext; // Really a "PragmaVisStack*"
 
-  /// This represents the stack of attributes that were pushed by
-  /// \#pragma clang attribute.
+  /// This an attribute introduced by \#pragma clang attribute.
   struct PragmaAttributeEntry {
 SourceLocation Loc;
 ParsedAttr *Attribute;
 SmallVector MatchRules;
 bool IsUsed;
   };
-  SmallVector PragmaAttributeStack;
+
+  /// A push'd group of PragmaAttributeEntries.
+  struct PragmaAttributeGroup {
+/// The location of the push attribute.
+SourceLocation Loc;
+SmallVector Entries;
+  };
+
+  SmallVector PragmaAttributeStack;
 
   /// The declaration that is currently receiving an attribute from the
   /// #pragma attribute stack.
@@ -8470,9 +8477,10 @@
   /// the appropriate attribute.
   void AddCFAuditedAttribute(Decl *D);
 
-  /// Called on well-formed '\#pragma clang attribute push'.
-  void ActOnPragmaAttributePush(ParsedAttr , SourceLocation PragmaLoc,
-attr::ParsedSubjectMatchRuleSet Rules);
+  void ActOnPragmaAttributeAttribute(ParsedAttr ,
+ SourceLocation PragmaLoc,
+ attr::ParsedSubjectMatchRuleSet Rules);
+  void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc);
 
   /// Called on well-formed '\#pragma clang attribute pop'.
   void ActOnPragmaAttributePop(SourceLocation PragmaLoc);
Index: 

[PATCH] D53621: Support for groups of attributes in #pragma clang attribute

2018-10-28 Thread Erik Pilkington via Phabricator via cfe-commits
erik.pilkington marked an inline comment as done.
erik.pilkington added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:2666
 
-  #pragma clang attribute push(__attribute__((annotate("custom"))), apply_to = 
function)
+  #pragma clang attribute push (__attribute__((annotate("custom"))), apply_to 
= function)
 

aaron.ballman wrote:
> The whitespace changes here are not needed as part of this patch, right? 
> (It's just changing the style of the docs?)
Oh, no it doesn't make a difference to clang. Just thought that it makes it a 
bit more obvious that this operation is a combination of:
```
#pragma clang attribute push
#pragma clang attribute (__attribute__((annotate("custom"))), apply_to = 
function)
```



Comment at: clang/lib/Parse/ParsePragma.cpp:3149
   else {
-PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
-<< PP.getSpelling(Tok);
-return;
+const auto *II = Tok.getIdentifierInfo();
+if (II->isStr("push"))

aaron.ballman wrote:
> I'd prefer dropping the `auto` here.
Sure, done in the commit. Thanks for reviewing!


https://reviews.llvm.org/D53621



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


r345486 - Support for groups of attributes in #pragma clang attribute

2018-10-28 Thread Erik Pilkington via cfe-commits
Author: epilk
Date: Sun Oct 28 19:29:21 2018
New Revision: 345486

URL: http://llvm.org/viewvc/llvm-project?rev=345486=rev
Log:
Support for groups of attributes in #pragma clang attribute

This commit enables pushing an empty #pragma clang attribute push, then adding
multiple attributes to it, then popping them all with #pragma clang attribute
pop, just like #pragma clang diagnostic. We still support the current way of
adding these, #pragma clang attribute push(__attribute__((...))), by treating it
like a combined push/attribute. This is needed to create macros like:

DO_SOMETHING_BEGIN(attr1, attr2, attr3)
// ...
DO_SOMETHING_END

rdar://45496947

Differential revision: https://reviews.llvm.org/D53621

Modified:
cfe/trunk/docs/LanguageExtensions.rst
cfe/trunk/docs/ReleaseNotes.rst
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParsePragma.cpp
cfe/trunk/lib/Sema/SemaAttr.cpp
cfe/trunk/test/Parser/pragma-attribute.cpp
cfe/trunk/test/Sema/pragma-attribute.c

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=345486=345485=345486=diff
==
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Sun Oct 28 19:29:21 2018
@@ -2651,17 +2651,19 @@ Specifying an attribute for multiple dec
 
 The ``#pragma clang attribute`` directive can be used to apply an attribute to
 multiple declarations. The ``#pragma clang attribute push`` variation of the
-directive pushes a new attribute to the attribute stack. The declarations that
-follow the pragma receive the attributes that are on the attribute stack, until
-the stack is cleared using a ``#pragma clang attribute pop`` directive. 
Multiple
-push directives can be nested inside each other.
+directive pushes a new "scope" of ``#pragma clang attribute`` that attributes
+can be added to. The ``#pragma clang attribute (...)`` variation adds an
+attribute to that scope, and the ``#pragma clang attribute pop`` variation pops
+the scope. You can also use ``#pragma clang attribute push (...)``, which is a
+shorthand for when you want to add one attribute to a new scope. Multiple push
+directives can be nested inside each other.
 
 The attributes that are used in the ``#pragma clang attribute`` directives
 can be written using the GNU-style syntax:
 
 .. code-block:: c++
 
-  #pragma clang attribute push(__attribute__((annotate("custom"))), apply_to = 
function)
+  #pragma clang attribute push (__attribute__((annotate("custom"))), apply_to 
= function)
 
   void function(); // The function now has the annotate("custom") attribute
 
@@ -2671,7 +2673,7 @@ The attributes can also be written using
 
 .. code-block:: c++
 
-  #pragma clang attribute push([[noreturn]], apply_to = function)
+  #pragma clang attribute push ([[noreturn]], apply_to = function)
 
   void function(); // The function now has the [[noreturn]] attribute
 
@@ -2681,7 +2683,7 @@ The ``__declspec`` style syntax is also
 
 .. code-block:: c++
 
-  #pragma clang attribute push(__declspec(dllexport), apply_to = function)
+  #pragma clang attribute push (__declspec(dllexport), apply_to = function)
 
   void function(); // The function now has the __declspec(dllexport) attribute
 

Modified: cfe/trunk/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=345486=345485=345486=diff
==
--- cfe/trunk/docs/ReleaseNotes.rst (original)
+++ cfe/trunk/docs/ReleaseNotes.rst Sun Oct 28 19:29:21 2018
@@ -86,8 +86,8 @@ Modified Compiler Flags
 New Pragmas in Clang
 
 
-Clang now supports the ...
-
+- Clang now supports adding multiple ``#pragma clang attribute`` attributes 
into
+  a "scope" of ``push``ed attributes.
 
 Attribute Changes in Clang
 --

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=345486=345485=345486=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sun Oct 28 19:29:21 
2018
@@ -1032,8 +1032,8 @@ def err_pragma_optimize_invalid_argument
 def err_pragma_optimize_extra_argument : Error<
   "unexpected extra argument '%0' to '#pragma clang optimize'">;
 // - #pragma clang attribute
-def err_pragma_attribute_expected_push_pop : Error<
-  "expected 'push' or 'pop' after '#pragma clang attribute'">;
+def err_pragma_attribute_expected_push_pop_paren : Error<
+  "expected 'push', 'pop', or '(' after '#pragma clang attribute'">;
 def 

[PATCH] D33672: [analyzer] INT50-CPP. Do not cast to an out-of-range enumeration checker

2018-10-28 Thread Alexander Zaitsev via Phabricator via cfe-commits
ZaMaZaN4iK updated this revision to Diff 171443.

https://reviews.llvm.org/D33672

Files:
  include/clang/StaticAnalyzer/Checkers/Checkers.td
  lib/StaticAnalyzer/Checkers/CMakeLists.txt
  lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
  test/Analysis/enum-cast-out-of-range.cpp
  www/analyzer/alpha_checks.html

Index: www/analyzer/alpha_checks.html
===
--- www/analyzer/alpha_checks.html
+++ www/analyzer/alpha_checks.html
@@ -348,6 +348,24 @@
 }
 
 
+
+alpha.cplusplus.EnumCastOutOfRange
+(C++)
+  Check for integer to enumeration casts that could result in undefined values.
+
+  
+
+enum TestEnum {
+  A = 0
+};
+
+void foo() {
+  TestEnum t = static_cast(-1);
+  // warn: the value provided to the cast expression is not in
+   the valid range of values for the enum
+}
+
+
 
 
 alpha.cplusplus.InvalidatedIterator
Index: test/Analysis/enum-cast-out-of-range.cpp
===
--- /dev/null
+++ test/Analysis/enum-cast-out-of-range.cpp
@@ -0,0 +1,182 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:   -analyzer-checker=core,alpha.cplusplus.EnumCastOutOfRange \
+// RUN:   -std=c++11 -verify %s
+
+enum unscoped_unspecified_t {
+  unscoped_unspecified_0 = -4,
+  unscoped_unspecified_1,
+  unscoped_unspecified_2 = 1,
+  unscoped_unspecified_3,
+  unscoped_unspecified_4 = 4
+};
+
+enum unscoped_specified_t : int {
+  unscoped_specified_0 = -4,
+  unscoped_specified_1,
+  unscoped_specified_2 = 1,
+  unscoped_specified_3,
+  unscoped_specified_4 = 4
+};
+
+enum class scoped_unspecified_t {
+  scoped_unspecified_0 = -4,
+  scoped_unspecified_1,
+  scoped_unspecified_2 = 1,
+  scoped_unspecified_3,
+  scoped_unspecified_4 = 4
+};
+
+enum class scoped_specified_t : int {
+  scoped_specified_0 = -4,
+  scoped_specified_1,
+  scoped_specified_2 = 1,
+  scoped_specified_3,
+  scoped_specified_4 = 4
+};
+
+void unscopedUnspecified() {
+  unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast(-5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidNegativeValue1 = static_cast(-4); // OK.
+  unscoped_unspecified_t ValidNegativeValue2 = static_cast(-3); // OK.
+  unscoped_unspecified_t InvalidInsideRange1 = static_cast(-2); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t InvalidInsideRange2 = static_cast(-1); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t InvalidInsideRange3 = static_cast(0); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidPositiveValue1 = static_cast(1); // OK.
+  unscoped_unspecified_t ValidPositiveValue2 = static_cast(2); // OK.
+  unscoped_unspecified_t InvalidInsideRange4 = static_cast(3); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidPositiveValue3 = static_cast(4); // OK.
+  unscoped_unspecified_t InvalidAfterRangeEnd = static_cast(5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+}
+
+void unscopedSpecified() {
+  unscoped_specified_t InvalidBeforeRangeBegin = static_cast(-5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidNegativeValue1 = static_cast(-4); // OK.
+  unscoped_specified_t ValidNegativeValue2 = static_cast(-3); // OK.
+  unscoped_specified_t InvalidInsideRange1 = static_cast(-2); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t InvalidInsideRange2 = static_cast(-1); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t InvalidInsideRange3 = static_cast(0); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidPositiveValue1 = static_cast(1); // OK.
+  unscoped_specified_t ValidPositiveValue2 = static_cast(2); // OK.
+  unscoped_specified_t InvalidInsideRange4 = static_cast(3); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidPositiveValue3 = static_cast(4); // OK.
+  unscoped_specified_t InvalidAfterRangeEnd = static_cast(5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+}
+
+void scopedUnspecified() {
+  scoped_unspecified_t InvalidBeforeRangeBegin = static_cast(-5); // 

[PATCH] D33672: [analyzer] INT50-CPP. Do not cast to an out-of-range enumeration checker

2018-10-28 Thread Umann Kristóf via Phabricator via cfe-commits
Szelethus added a comment.

Please reupload with full context. 
(https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface)


https://reviews.llvm.org/D33672



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


[PATCH] D33672: [analyzer] INT50-CPP. Do not cast to an out-of-range enumeration checker

2018-10-28 Thread Alexander Zaitsev via Phabricator via cfe-commits
ZaMaZaN4iK updated this revision to Diff 171438.
ZaMaZaN4iK added a comment.

1. Changed std::transform to llvm::transform
2. Described the check in .html file
3. Fixed RUN command for the test file


https://reviews.llvm.org/D33672

Files:
  include/clang/StaticAnalyzer/Checkers/Checkers.td
  lib/StaticAnalyzer/Checkers/CMakeLists.txt
  lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
  test/Analysis/enum-cast-out-of-range.cpp
  www/analyzer/alpha_checks.html

Index: www/analyzer/alpha_checks.html
===
--- www/analyzer/alpha_checks.html
+++ www/analyzer/alpha_checks.html
@@ -348,6 +348,24 @@
 }
 
 
+
+alpha.cplusplus.EnumCastOutOfRange
+(C++)
+  Check for integer to enumeration casts that could result in undefined values.
+
+  
+
+enum TestEnum {
+  A = 0
+};
+
+void foo() {
+  TestEnum t = static_cast(-1);
+  // warn: the value provided to the cast expression is not in
+   the valid range of values for the enum
+}
+
+
 
 
 alpha.cplusplus.InvalidatedIterator
Index: test/Analysis/enum-cast-out-of-range.cpp
===
--- /dev/null
+++ test/Analysis/enum-cast-out-of-range.cpp
@@ -0,0 +1,182 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:   -analyzer-checker=core,alpha.cplusplus.EnumCastOutOfRange \
+// RUN:   -std=c++11 -verify %s
+
+enum unscoped_unspecified_t {
+  unscoped_unspecified_0 = -4,
+  unscoped_unspecified_1,
+  unscoped_unspecified_2 = 1,
+  unscoped_unspecified_3,
+  unscoped_unspecified_4 = 4
+};
+
+enum unscoped_specified_t : int {
+  unscoped_specified_0 = -4,
+  unscoped_specified_1,
+  unscoped_specified_2 = 1,
+  unscoped_specified_3,
+  unscoped_specified_4 = 4
+};
+
+enum class scoped_unspecified_t {
+  scoped_unspecified_0 = -4,
+  scoped_unspecified_1,
+  scoped_unspecified_2 = 1,
+  scoped_unspecified_3,
+  scoped_unspecified_4 = 4
+};
+
+enum class scoped_specified_t : int {
+  scoped_specified_0 = -4,
+  scoped_specified_1,
+  scoped_specified_2 = 1,
+  scoped_specified_3,
+  scoped_specified_4 = 4
+};
+
+void unscopedUnspecified() {
+  unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast(-5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidNegativeValue1 = static_cast(-4); // OK.
+  unscoped_unspecified_t ValidNegativeValue2 = static_cast(-3); // OK.
+  unscoped_unspecified_t InvalidInsideRange1 = static_cast(-2); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t InvalidInsideRange2 = static_cast(-1); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t InvalidInsideRange3 = static_cast(0); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidPositiveValue1 = static_cast(1); // OK.
+  unscoped_unspecified_t ValidPositiveValue2 = static_cast(2); // OK.
+  unscoped_unspecified_t InvalidInsideRange4 = static_cast(3); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidPositiveValue3 = static_cast(4); // OK.
+  unscoped_unspecified_t InvalidAfterRangeEnd = static_cast(5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+}
+
+void unscopedSpecified() {
+  unscoped_specified_t InvalidBeforeRangeBegin = static_cast(-5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidNegativeValue1 = static_cast(-4); // OK.
+  unscoped_specified_t ValidNegativeValue2 = static_cast(-3); // OK.
+  unscoped_specified_t InvalidInsideRange1 = static_cast(-2); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t InvalidInsideRange2 = static_cast(-1); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t InvalidInsideRange3 = static_cast(0); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidPositiveValue1 = static_cast(1); // OK.
+  unscoped_specified_t ValidPositiveValue2 = static_cast(2); // OK.
+  unscoped_specified_t InvalidInsideRange4 = static_cast(3); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidPositiveValue3 = static_cast(4); // OK.
+  unscoped_specified_t InvalidAfterRangeEnd = static_cast(5); // expected-warning {{the value provided to the cast expression is not in the valid 

[PATCH] D33672: [analyzer] INT50-CPP. Do not cast to an out-of-range enumeration checker

2018-10-28 Thread Alexander Zaitsev via Phabricator via cfe-commits
ZaMaZaN4iK commandeered this revision.
ZaMaZaN4iK added a reviewer: gamesh411.
ZaMaZaN4iK added inline comments.



Comment at: lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp:19
+//   of casting an integer value that is out of range
+//===--===//
+

aaron.ballman wrote:
> If this check is intended to conform to CERT's INT50-CPP rule, you should put 
> a link to the wiki entry for it here as well.
Which wiki entry do you mean?


https://reviews.llvm.org/D33672



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


r345479 - AST: extend MS decoration handling for extended vectors

2018-10-28 Thread Saleem Abdulrasool via cfe-commits
Author: compnerd
Date: Sun Oct 28 11:05:20 2018
New Revision: 345479

URL: http://llvm.org/viewvc/llvm-project?rev=345479=rev
Log:
AST: extend MS decoration handling for extended vectors

We correctly handled extended vectors of non-floating point types.
However, we have the Intel style builtins which MSVC also supports which
do overlap in sizes with the floating point extended vectors.  This
would result in overloading of floating point extended vector types
which matched sizes (e.g. <3 x float> would be backed by a <4 x float>
and thus match sizes) to be mangled similarly.  Extended vectors are a
clang extension which live outside of the builtins, so mangle them all
similarly.  This change just extends the current scheme to treat
floating point types similar to the way that we treat other types
currently.

This now allows the swift runtime to be built for Windows again.

Modified:
cfe/trunk/lib/AST/MicrosoftMangle.cpp
cfe/trunk/test/CodeGenCXX/mangle-ms-vector-types.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=345479=345478=345479=diff
==
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Sun Oct 28 11:05:20 2018
@@ -2569,18 +2569,20 @@ void MicrosoftCXXNameMangler::mangleType
   // Pattern match exactly the typedefs in our intrinsic headers.  Anything 
that
   // doesn't match the Intel types uses a custom mangling below.
   size_t OutSizeBefore = Out.tell();
-  llvm::Triple::ArchType AT =
-  getASTContext().getTargetInfo().getTriple().getArch();
-  if (AT == llvm::Triple::x86 || AT == llvm::Triple::x86_64) {
-if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
-  mangleArtificalTagType(TTK_Union, "__m64");
-} else if (Width >= 128) {
-  if (ET->getKind() == BuiltinType::Float)
-mangleArtificalTagType(TTK_Union, "__m" + llvm::utostr(Width));
-  else if (ET->getKind() == BuiltinType::LongLong)
-mangleArtificalTagType(TTK_Union, "__m" + llvm::utostr(Width) + 'i');
-  else if (ET->getKind() == BuiltinType::Double)
-mangleArtificalTagType(TTK_Struct, "__m" + llvm::utostr(Width) + 'd');
+  if (!isa(T)) {
+llvm::Triple::ArchType AT =
+getASTContext().getTargetInfo().getTriple().getArch();
+if (AT == llvm::Triple::x86 || AT == llvm::Triple::x86_64) {
+  if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
+mangleArtificalTagType(TTK_Union, "__m64");
+  } else if (Width >= 128) {
+if (ET->getKind() == BuiltinType::Float)
+  mangleArtificalTagType(TTK_Union, "__m" + llvm::utostr(Width));
+else if (ET->getKind() == BuiltinType::LongLong)
+  mangleArtificalTagType(TTK_Union, "__m" + llvm::utostr(Width) + 'i');
+else if (ET->getKind() == BuiltinType::Double)
+  mangleArtificalTagType(TTK_Struct, "__m" + llvm::utostr(Width) + 
'd');
+  }
 }
   }
 

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-vector-types.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-vector-types.cpp?rev=345479=345478=345479=diff
==
--- cfe/trunk/test/CodeGenCXX/mangle-ms-vector-types.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-vector-types.cpp Sun Oct 28 11:05:20 
2018
@@ -94,5 +94,9 @@ typedef __attribute__((ext_vector_type(4
 void foovi4b(vi4b) {}
 // CHECK: define dso_local void @"?foovi4b@@YAXT?$__vector@H$03@__clang@@@Z"
 
+typedef float __attribute__((__ext_vector_type__(3))) vf3;
+void foovf3(vf3) {}
+// CHECK: define dso_local void @"?foovf3@@YAXT?$__vector@M$02@__clang@@@Z"
+
 // Clang does not support vectors of complex types, so we can't test the
 // mangling of them.


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


Re: [PATCH] D53354: [WIP][NOT FOR COMMIT][PROTOTYPE] clang-scan-deps: dependency scanning tool rough prototype

2018-10-28 Thread Kim Gräsman via cfe-commits
Hi Alex,

On Fri, Oct 19, 2018 at 1:11 AM Alex Lorenz via Phabricator via
cfe-commits  wrote:
>
> > Have you checked the tool //Include What You Use//? I'm curious in what way 
> > the mishappenings of that tool present themselves in yours. There were some 
> > challenges not overcome in a good way in IWYU, their readme goes into a bit 
> > more detail on this.
>
> I haven't looked into IWYU that much. Could you please elaborate on which 
> mishappenings you think might present themselves here?

IWYU maintainer here.

I'm not sure exactly what your tool wants to do, or what Whisperity
meant, but we have a couple of doc pages on why IWYU is tricky:
https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/WhatIsAUse.md
https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/WhyIWYUIsDifficult.md

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


r345477 - [AST] Fix an use-of-uninitialized bug introduced in CaseStmt

2018-10-28 Thread Bruno Ricci via cfe-commits
Author: brunoricci
Date: Sun Oct 28 07:14:06 2018
New Revision: 345477

URL: http://llvm.org/viewvc/llvm-project?rev=345477=rev
Log:
[AST] Fix an use-of-uninitialized bug introduced in CaseStmt

SwitchCaseBits.CaseStmtIsGNURange needs to be initialized first.


Modified:
cfe/trunk/include/clang/AST/Stmt.h

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=345477=345476=345477=diff
==
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Sun Oct 28 07:14:06 2018
@@ -975,11 +975,11 @@ class CaseStmt final
   CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
SourceLocation ellipsisLoc, SourceLocation colonLoc)
   : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
-setLHS(lhs);
-setSubStmt(nullptr);
 // Handle GNU case statements of the form LHS ... RHS.
 bool IsGNURange = rhs != nullptr;
 SwitchCaseBits.CaseStmtIsGNURange = IsGNURange;
+setLHS(lhs);
+setSubStmt(nullptr);
 if (IsGNURange) {
   setRHS(rhs);
   setEllipsisLoc(ellipsisLoc);


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


[PATCH] D53771: [clang-tidy] Avoid C arrays check

2018-10-28 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added inline comments.



Comment at: docs/clang-tidy/checks/cppcoreguidelines-avoid-c-arrays.rst:6
+cppcoreguidelines-avoid-c-arrays
+=
+

Eugene.Zelenko wrote:
> Please make same length as header.
Whoops, i noticed that in the main doc, but not here, sorry.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53771



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


[PATCH] D53771: [clang-tidy] Avoid C arrays check

2018-10-28 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri updated this revision to Diff 171425.
lebedev.ri marked 3 inline comments as done.
lebedev.ri added a comment.

Docs fixes.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53771

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/hicpp/HICPPTidyModule.cpp
  clang-tidy/modernize/AvoidCArraysCheck.cpp
  clang-tidy/modernize/AvoidCArraysCheck.h
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ModernizeTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-avoid-c-arrays.rst
  docs/clang-tidy/checks/hicpp-avoid-c-arrays.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-avoid-c-arrays.rst
  test/clang-tidy/modernize-avoid-c-arrays.cpp

Index: test/clang-tidy/modernize-avoid-c-arrays.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-avoid-c-arrays.cpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int a[] = {1, 2};
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+int b[1];
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+void foo() {
+  int c[b[0]];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+}
+
+template 
+class array {
+  T d[Size];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+  int e[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+
+array d;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead
+
+using k = int[4];
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not declare C-style arrays, use std::array<> instead
+
+array dk;
+
+template 
+class unique_ptr {
+  T *d;
+
+  int e[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+
+unique_ptr d2;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead
+
+using k2 = int[];
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead
+
+unique_ptr dk2;
+
+// Some header
+extern "C" {
+
+int f[] = {1, 2};
+
+int j[1];
+
+inline void bar() {
+  {
+int j[j[0]];
+  }
+}
+}
Index: docs/clang-tidy/checks/modernize-avoid-c-arrays.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-avoid-c-arrays.rst
@@ -0,0 +1,57 @@
+.. title:: clang-tidy - modernize-avoid-c-arrays
+
+modernize-avoid-c-arrays
+
+
+`cppcoreguidelines-avoid-c-arrays` redirects here as an alias for this check.
+
+`hicpp-avoid-c-arrays` redirects here as an alias for this check.
+
+Finds C-style array types and recommend to use ``std::array<>``.
+All types of C arrays are diagnosed.
+
+However, no fix-its are provided. Such transform would need to be able to
+observe *all* the uses of said declaration in order to decide whether it is
+safe to transform or not, and that is impossible in case of headers.
+
+.. code:: c++
+
+  int a[] = {1, 2}; // warning: do not declare C-style arrays, use std::array<> instead
+
+  int b[1]; // warning: do not declare C-style arrays, use std::array<> instead
+
+  void foo() {
+int c[b[0]]; // warning: do not declare C-style arrays, use std::array<> instead
+  }
+
+  template 
+  class array {
+T d[Size]; // warning: do not declare C-style arrays, use std::array<> instead
+
+int e[1]; // warning: do not declare C-style arrays, use std::array<> instead
+  };
+
+  array d; // warning: do not declare C-style arrays, use std::array<> instead
+
+  using k = int[4]; // warning: do not declare C-style arrays, use std::array<> instead
+
+
+However, the ``extern "C"`` code is ignored, since it is common to share
+such headers between C code, and C++ code.
+
+.. code:: c++
+
+  // Some header
+  extern "C" {
+
+  int f[] = {1, 2}; // not diagnosed
+
+  int j[1]; // not diagnosed
+
+  inline void bar() {
+{
+  int j[j[0]]; // not diagnosed
+}
+  }
+
+  }
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -87,6 +87,7 @@
cert-msc51-cpp
cert-oop11-cpp (redirects to performance-move-constructor-init) 
cppcoreguidelines-avoid-goto
+   cppcoreguidelines-avoid-c-arrays (redirects to modernize-avoid-c-arrays) 
cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) 
cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) 
cppcoreguidelines-interfaces-global-init
@@ -131,6 +132,7 @@
google-runtime-int

[PATCH] D53771: [clang-tidy] Avoid C arrays check

2018-10-28 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: docs/clang-tidy/checks/cppcoreguidelines-avoid-c-arrays.rst:6
+cppcoreguidelines-avoid-c-arrays
+=
+

Please make same length as header.



Comment at: docs/clang-tidy/checks/hicpp-avoid-c-arrays.rst:8
+
+The hicpp-avoid-c-arrays check is an alias,
+please see

Please fill as much as possible to 80 character. Probably same for other alias.



Comment at: docs/clang-tidy/checks/modernize-avoid-c-arrays.rst:6
+
+`cppcoreguidelines-avoid-c-arrays` redirects here
+as an alias for this check.

Please fill as much as possible to 80 character. Same for other alias.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53771



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


[PATCH] D53771: [clang-tidy] Avoid C arrays check

2018-10-28 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri updated this revision to Diff 171423.
lebedev.ri added a comment.
Herald added subscribers: kbarton, nemanjai.

In https://reviews.llvm.org/D53771#1278177, @Eugene.Zelenko wrote:

> Will be good idea to add aliases at least for existing modules.


Added CPPCG, HICPP aliases.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53771

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/hicpp/HICPPTidyModule.cpp
  clang-tidy/modernize/AvoidCArraysCheck.cpp
  clang-tidy/modernize/AvoidCArraysCheck.h
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ModernizeTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-avoid-c-arrays.rst
  docs/clang-tidy/checks/hicpp-avoid-c-arrays.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-avoid-c-arrays.rst
  test/clang-tidy/modernize-avoid-c-arrays.cpp

Index: test/clang-tidy/modernize-avoid-c-arrays.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-avoid-c-arrays.cpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int a[] = {1, 2};
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+int b[1];
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+void foo() {
+  int c[b[0]];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+}
+
+template 
+class array {
+  T d[Size];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+  int e[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+
+array d;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead
+
+using k = int[4];
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not declare C-style arrays, use std::array<> instead
+
+array dk;
+
+template 
+class unique_ptr {
+  T *d;
+
+  int e[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+
+unique_ptr d2;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead
+
+using k2 = int[];
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead
+
+unique_ptr dk2;
+
+// Some header
+extern "C" {
+
+int f[] = {1, 2};
+
+int j[1];
+
+inline void bar() {
+  {
+int j[j[0]];
+  }
+}
+}
Index: docs/clang-tidy/checks/modernize-avoid-c-arrays.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-avoid-c-arrays.rst
@@ -0,0 +1,59 @@
+.. title:: clang-tidy - modernize-avoid-c-arrays
+
+modernize-avoid-c-arrays
+
+
+`cppcoreguidelines-avoid-c-arrays` redirects here
+as an alias for this check.
+
+`hicpp-avoid-c-arrays` redirects here
+as an alias for this check.
+
+Finds C-style array types and recommend to use ``std::array<>``.
+All types of C arrays are diagnosed.
+
+However, no fix-its are provided. Such transform would need to be able to
+observe *all* the uses of said declaration in order to decide whether it is
+safe to transform or not, and that is impossible in case of headers.
+
+.. code:: c++
+
+  int a[] = {1, 2}; // warning: do not declare C-style arrays, use std::array<> instead
+
+  int b[1]; // warning: do not declare C-style arrays, use std::array<> instead
+
+  void foo() {
+int c[b[0]]; // warning: do not declare C-style arrays, use std::array<> instead
+  }
+
+  template 
+  class array {
+T d[Size]; // warning: do not declare C-style arrays, use std::array<> instead
+
+int e[1]; // warning: do not declare C-style arrays, use std::array<> instead
+  };
+
+  array d; // warning: do not declare C-style arrays, use std::array<> instead
+
+  using k = int[4]; // warning: do not declare C-style arrays, use std::array<> instead
+
+
+However, the ``extern "C"`` code is ignored, since it is common to share
+such headers between C code, and C++ code.
+
+.. code:: c++
+
+  // Some header
+  extern "C" {
+
+  int f[] = {1, 2}; // not diagnosed
+
+  int j[1]; // not diagnosed
+
+  inline void bar() {
+{
+  int j[j[0]]; // not diagnosed
+}
+  }
+
+  }
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -87,6 +87,7 @@
cert-msc51-cpp
cert-oop11-cpp (redirects to performance-move-constructor-init) 
cppcoreguidelines-avoid-goto
+   cppcoreguidelines-avoid-c-arrays (redirects to modernize-avoid-c-arrays) 
cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) 

[PATCH] D52984: [analyzer] Checker reviewer's checklist

2018-10-28 Thread Umann Kristóf via Phabricator via cfe-commits
Szelethus added a comment.

One more thing.

From what I've seen, new checkers are in an overwhelming majority (again, from 
what **I've** seen) made by beginners, so I'd propose to include comments in 
checkers that are at least in part understandable by a beginner. I don't mean 
to make make 60% of the code grey, but there are a lot of unexplained 
non-trivial hackery in some.


https://reviews.llvm.org/D52984



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


[PATCH] D53609: [AST] Don't store data for GNU range case statement if not needed.

2018-10-28 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC345472: [AST] Dont store data for GNU range case 
statement if not needed (authored by brunoricci, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D53609

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/switch-stmt/test.cpp
  test/Misc/ast-dump-color.cpp

Index: lib/AST/ASTDumper.cpp
===
--- lib/AST/ASTDumper.cpp
+++ lib/AST/ASTDumper.cpp
@@ -515,6 +515,7 @@
 void VisitLabelStmt(const LabelStmt *Node);
 void VisitGotoStmt(const GotoStmt *Node);
 void VisitCXXCatchStmt(const CXXCatchStmt *Node);
+void VisitCaseStmt(const CaseStmt *Node);
 void VisitCapturedStmt(const CapturedStmt *Node);
 
 // OpenMP
@@ -2047,6 +2048,12 @@
   dumpDecl(Node->getExceptionDecl());
 }
 
+void ASTDumper::VisitCaseStmt(const CaseStmt *Node) {
+  VisitStmt(Node);
+  if (Node->caseStmtIsGNURange())
+OS << " gnu_range";
+}
+
 void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) {
   VisitStmt(Node);
   dumpDecl(Node->getCapturedDecl());
Index: lib/AST/Stmt.cpp
===
--- lib/AST/Stmt.cpp
+++ lib/AST/Stmt.cpp
@@ -942,12 +942,6 @@
VarRange.getEnd());
 }
 
-Stmt *SwitchCase::getSubStmt() {
-  if (isa(this))
-return cast(this)->getSubStmt();
-  return cast(this)->getSubStmt();
-}
-
 WhileStmt::WhileStmt(const ASTContext , VarDecl *Var, Expr *cond, Stmt *body,
  SourceLocation WL)
   : Stmt(WhileStmtClass) {
@@ -991,6 +985,27 @@
   return cast_or_null(RetExpr);
 }
 
+// CaseStmt
+CaseStmt *CaseStmt::Create(const ASTContext , Expr *lhs, Expr *rhs,
+   SourceLocation caseLoc, SourceLocation ellipsisLoc,
+   SourceLocation colonLoc) {
+  bool CaseStmtIsGNURange = rhs != nullptr;
+  void *Mem = Ctx.Allocate(
+  totalSizeToAlloc(
+  NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
+  alignof(CaseStmt));
+  return new (Mem) CaseStmt(lhs, rhs, caseLoc, ellipsisLoc, colonLoc);
+}
+
+CaseStmt *CaseStmt::CreateEmpty(const ASTContext ,
+bool CaseStmtIsGNURange) {
+  void *Mem = Ctx.Allocate(
+  totalSizeToAlloc(
+  NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
+  alignof(CaseStmt));
+  return new (Mem) CaseStmt(EmptyShell(), CaseStmtIsGNURange);
+}
+
 SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
Stmt *Handler)
 : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
Index: lib/AST/ASTImporter.cpp
===
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -5707,8 +5707,8 @@
   std::tie(ToLHS, ToRHS, ToSubStmt, ToCaseLoc, ToEllipsisLoc, ToColonLoc) =
   *Imp;
 
-  auto *ToStmt = new (Importer.getToContext()) CaseStmt(
-  ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc);
+  auto *ToStmt = CaseStmt::Create(Importer.getToContext(), ToLHS, ToRHS,
+  ToCaseLoc, ToEllipsisLoc, ToColonLoc);
   ToStmt->setSubStmt(ToSubStmt);
 
   return ToStmt;
Index: lib/Sema/SemaStmt.cpp
===
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -462,17 +462,17 @@
 return StmtError();
   }
 
-  CaseStmt *CS = new (Context)
-  CaseStmt(LHSVal.get(), RHSVal.get(), CaseLoc, DotDotDotLoc, ColonLoc);
+  auto *CS = CaseStmt::Create(Context, LHSVal.get(), RHSVal.get(),
+  CaseLoc, DotDotDotLoc, ColonLoc);
   getCurFunction()->SwitchStack.back().getPointer()->addSwitchCase(CS);
   return CS;
 }
 
 /// ActOnCaseStmtBody - This installs a statement as the body of a case.
 void Sema::ActOnCaseStmtBody(Stmt *caseStmt, Stmt *SubStmt) {
   DiagnoseUnusedExprResult(SubStmt);
 
-  CaseStmt *CS = static_cast(caseStmt);
+  auto *CS = static_cast(caseStmt);
   CS->setSubStmt(SubStmt);
 }
 
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -96,10 +96,13 @@
 
 void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
   VisitSwitchCase(S);
+  Record.push_back(S->caseStmtIsGNURange());
   Record.AddStmt(S->getLHS());
-  Record.AddStmt(S->getRHS());
   Record.AddStmt(S->getSubStmt());
-  Record.AddSourceLocation(S->getEllipsisLoc());
+  if (S->caseStmtIsGNURange()) {
+Record.AddStmt(S->getRHS());
+Record.AddSourceLocation(S->getEllipsisLoc());
+  }
   Code = serialization::STMT_CASE;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp

r345472 - [AST] Don't store data for GNU range case statement if not needed

2018-10-28 Thread Bruno Ricci via cfe-commits
Author: brunoricci
Date: Sun Oct 28 05:30:53 2018
New Revision: 345472

URL: http://llvm.org/viewvc/llvm-project?rev=345472=rev
Log:
[AST] Don't store data for GNU range case statement if not needed

Don't store the data for case statements of the form LHS ... RHS if not
needed. This cuts the size of CaseStmt by 1 pointer + 1 SourceLocation in
the common case.

Also use the newly available space in the bit-fields of Stmt to store the
keyword location of SwitchCase and move the small accessor
SwitchCase::getSubStmt to the header.

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

Reviewed By: rjmccall


Modified:
cfe/trunk/include/clang/AST/Stmt.h
cfe/trunk/lib/AST/ASTDumper.cpp
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/Stmt.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
cfe/trunk/test/Import/switch-stmt/test.cpp
cfe/trunk/test/Misc/ast-dump-color.cpp

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=345472=345471=345472=diff
==
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Sun Oct 28 05:30:53 2018
@@ -245,6 +245,20 @@ protected:
 SourceLocation RetLoc;
   };
 
+  class SwitchCaseBitfields {
+friend class SwitchCase;
+friend class CaseStmt;
+
+unsigned : NumStmtBits;
+
+/// Used by CaseStmt to store whether it is a case statement
+/// of the form case LHS ... RHS (a GNU extension).
+unsigned CaseStmtIsGNURange : 1;
+
+/// The location of the "case" or "default" keyword.
+SourceLocation KeywordLoc;
+  };
+
   //===--- Expression bitfields classes ---===//
 
   class ExprBitfields {
@@ -461,6 +475,7 @@ protected:
 ContinueStmtBitfields ContinueStmtBits;
 BreakStmtBitfields BreakStmtBits;
 ReturnStmtBitfields ReturnStmtBits;
+SwitchCaseBitfields SwitchCaseBits;
 
 // Expressions
 ExprBitfields ExprBits;
@@ -877,36 +892,40 @@ public:
 // SwitchCase is the base class for CaseStmt and DefaultStmt,
 class SwitchCase : public Stmt {
 protected:
-  // A pointer to the following CaseStmt or DefaultStmt class,
-  // used by SwitchStmt.
-  SwitchCase *NextSwitchCase = nullptr;
-  SourceLocation KeywordLoc;
+  /// The location of the ":".
   SourceLocation ColonLoc;
 
+  // The location of the "case" or "default" keyword. Stored in SwitchCaseBits.
+  // SourceLocation KeywordLoc;
+
+  /// A pointer to the following CaseStmt or DefaultStmt class,
+  /// used by SwitchStmt.
+  SwitchCase *NextSwitchCase = nullptr;
+
   SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
-  : Stmt(SC), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {}
+  : Stmt(SC), ColonLoc(ColonLoc) {
+setKeywordLoc(KWLoc);
+  }
 
   SwitchCase(StmtClass SC, EmptyShell) : Stmt(SC) {}
 
 public:
   const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
-
   SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
-
   void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
 
-  SourceLocation getKeywordLoc() const { return KeywordLoc; }
-  void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
+  SourceLocation getKeywordLoc() const { return SwitchCaseBits.KeywordLoc; }
+  void setKeywordLoc(SourceLocation L) { SwitchCaseBits.KeywordLoc = L; }
   SourceLocation getColonLoc() const { return ColonLoc; }
   void setColonLoc(SourceLocation L) { ColonLoc = L; }
 
-  Stmt *getSubStmt();
+  inline Stmt *getSubStmt();
   const Stmt *getSubStmt() const {
-return const_cast(this)->getSubStmt();
+return const_cast(this)->getSubStmt();
   }
 
-  SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
-  SourceLocation getEndLoc() const LLVM_READONLY;
+  SourceLocation getBeginLoc() const { return getKeywordLoc(); }
+  inline SourceLocation getEndLoc() const LLVM_READONLY;
 
   static bool classof(const Stmt *T) {
 return T->getStmtClass() == CaseStmtClass ||
@@ -914,52 +933,137 @@ public:
   }
 };
 
-class CaseStmt : public SwitchCase {
-  SourceLocation EllipsisLoc;
-  enum { LHS, RHS, SUBSTMT, END_EXPR };
-  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
- // GNU "case 1 ... 4" extension
+/// CaseStmt - Represent a case statement. It can optionally be a GNU case
+/// statement of the form LHS ... RHS representing a range of cases.
+class CaseStmt final
+: public SwitchCase,
+  private llvm::TrailingObjects {
+  friend TrailingObjects;
 
-public:
+  // CaseStmt is followed by several trailing objects, some of which optional.
+  // Note that it would be more convenient to put the optional trailing objects
+  // at the end but this would impact children().
+  // The trailing objects are in order:
+  //
+  // * A "Stmt *" for the LHS of the case 

[PATCH] D36357: Added a better diagnostic when using the delete operator with lambdas

2018-10-28 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 171421.
Rakete added a comment.

Rebase and friendly ping :)


Repository:
  rC Clang

https://reviews.llvm.org/D36357

Files:
  include/clang/Basic/DiagnosticParseKinds.td
  lib/Parse/ParseExprCXX.cpp
  test/FixIt/fixit-cxx0x.cpp
  test/Parser/cxx0x-lambda-expressions.cpp
  test/SemaCXX/new-delete-0x.cpp

Index: test/SemaCXX/new-delete-0x.cpp
===
--- test/SemaCXX/new-delete-0x.cpp
+++ test/SemaCXX/new-delete-0x.cpp
@@ -34,6 +34,6 @@
 void bad_deletes()
 {
   // 'delete []' is always array delete, per [expr.delete]p1.
-  // FIXME: Give a better diagnostic.
-  delete []{ return (int*)0; }(); // expected-error {{expected expression}}
+  delete []{ return (int*)0; }(); // expected-error {{'[]' after delete interpreted as 'delete[]'}}
 }
+
Index: test/Parser/cxx0x-lambda-expressions.cpp
===
--- test/Parser/cxx0x-lambda-expressions.cpp
+++ test/Parser/cxx0x-lambda-expressions.cpp
@@ -53,8 +53,11 @@
   void delete_lambda(int *p) {
 delete [] p;
 delete [] (int*) { new int }; // ok, compound-literal, not lambda
-delete [] { return new int; } (); // expected-error{{expected expression}}
+delete [] { return new int; } (); // expected-error {{'[]' after delete interpreted as 'delete[]'}}
 delete [&] { return new int; } (); // ok, lambda
+
+delete []() { return new int; }(); // expected-error{{'[]' after delete interpreted as 'delete[]'}}
+delete [](E Enum) { return new int((int)Enum); }(e); // expected-error{{'[]' after delete interpreted as 'delete[]'}}
   }
 
   // We support init-captures in C++11 as an extension.
Index: test/FixIt/fixit-cxx0x.cpp
===
--- test/FixIt/fixit-cxx0x.cpp
+++ test/FixIt/fixit-cxx0x.cpp
@@ -58,6 +58,9 @@
   (void)[&, i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
   (void)[] mutable { }; // expected-error{{lambda requires '()' before 'mutable'}}
   (void)[] -> int { }; // expected-error{{lambda requires '()' before return type}}
+
+  delete []() { return new int; }(); // expected-error{{'[]' after delete interpreted as 'delete[]'}}
+  delete [] { return new int; }(); // expected-error{{'[]' after delete interpreted as 'delete[]'}}
 }
 
 #define bar "bar"
Index: lib/Parse/ParseExprCXX.cpp
===
--- lib/Parse/ParseExprCXX.cpp
+++ lib/Parse/ParseExprCXX.cpp
@@ -2976,8 +2976,38 @@
 //   [Footnote: A lambda expression with a lambda-introducer that consists
 //  of empty square brackets can follow the delete keyword if
 //  the lambda expression is enclosed in parentheses.]
-// FIXME: Produce a better diagnostic if the '[]' is unambiguously a
-//lambda-introducer.
+
+const Token Next = GetLookAheadToken(2);
+
+// Basic lookahead to check if we have a lambda expression.
+if (Next.isOneOf(tok::l_brace, tok::less) ||
+(Next.is(tok::l_paren) &&
+ (GetLookAheadToken(3).is(tok::r_paren) ||
+  (GetLookAheadToken(3).is(tok::identifier) &&
+   GetLookAheadToken(4).is(tok::identifier) {
+  SourceLocation RightBracketLock = NextToken().getLocation();
+  // Warn if the non-capturing lambda isn't surrounded by parenthesis
+  // to disambiguate it from 'delete[]'.
+  ExprResult Lambda = ParseLambdaExpression();
+  if (Lambda.isInvalid())
+return ExprError();
+
+  SourceLocation StartLoc = Lambda.get()->getBeginLoc();
+  Diag(Start, diag::err_lambda_after_delete)
+  << SourceRange(Start, RightBracketLock)
+  << FixItHint::CreateInsertion(StartLoc, "(")
+  << FixItHint::CreateInsertion(
+ Lexer::getLocForEndOfToken(Lambda.get()->getEndLoc(), 0,
+Actions.getSourceManager(),
+getLangOpts()),
+ ")");
+
+  // Evaluate any postfix expressions used on the lambda.
+  Lambda = ParsePostfixExpressionSuffix(Lambda);
+  return Actions.ActOnCXXDelete(Start, UseGlobal, /*ArrayForm=*/false,
+Lambda.get());
+}
+
 ArrayDelete = true;
 BalancedDelimiterTracker T(*this, tok::l_square);
 
Index: include/clang/Basic/DiagnosticParseKinds.td
===
--- include/clang/Basic/DiagnosticParseKinds.td
+++ include/clang/Basic/DiagnosticParseKinds.td
@@ -102,6 +102,8 @@
   InGroup, DefaultIgnore;
 def ext_alignof_expr : ExtWarn<
   "%0 applied to an expression is a GNU extension">, InGroup;
+def err_lambda_after_delete : Error<
+  "'[]' after delete interpreted as 'delete[]'">;
 
 def warn_microsoft_dependent_exists : Warning<
   "dependent %select{__if_not_exists|__if_exists}0 declarations are 

[PATCH] D53475: Create ConstantExpr class

2018-10-28 Thread Bill Wendling via Phabricator via cfe-commits
void marked 6 inline comments as done.
void added inline comments.



Comment at: lib/AST/StmtProfile.cpp:1001
+  VisitExpr(S);
+  VisitExpr(S->getSubExpr());
+}

rsmith wrote:
> This is unnecessary: this visitor visits the children of the node for you.
If I don't have this then the link fails because it cannot find this.


Repository:
  rC Clang

https://reviews.llvm.org/D53475



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


[PATCH] D53475: Create ConstantExpr class

2018-10-28 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 171417.
void marked an inline comment as done.

Repository:
  rC Clang

https://reviews.llvm.org/D53475

Files:
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/StmtDataCollectors.td
  include/clang/Basic/StmtNodes.td
  include/clang/Serialization/ASTBitCodes.h
  lib/ARCMigrate/TransAutoreleasePool.cpp
  lib/ARCMigrate/TransRetainReleaseDealloc.cpp
  lib/ARCMigrate/TransUnbridgedCasts.cpp
  lib/ARCMigrate/Transforms.cpp
  lib/AST/Decl.cpp
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/ParentMap.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/LiveVariables.cpp
  lib/Analysis/ThreadSafety.cpp
  lib/Analysis/ThreadSafetyCommon.cpp
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CGStmtOpenMP.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaInit.cpp
  lib/Sema/SemaOpenMP.cpp
  lib/Sema/SemaStmt.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  lib/StaticAnalyzer/Core/BugReporter.cpp
  lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
  lib/StaticAnalyzer/Core/Environment.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -343,6 +343,10 @@
 K = CXCursor_CharacterLiteral;
 break;
 
+  case Stmt::ConstantExprClass:
+return MakeCXCursor(cast(S)->getSubExpr(),
+Parent, TU, RegionOfInterest);
+
   case Stmt::ParenExprClass:
 K = CXCursor_ParenExpr;
 break;
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1267,6 +1267,9 @@
 case Stmt::ObjCPropertyRefExprClass:
   llvm_unreachable("These are handled by PseudoObjectExpr");
 
+case Expr::ConstantExprClass:
+  return Visit(cast(S)->getSubExpr(), Pred, DstTop);
+
 case Stmt::GNUNullExprClass: {
   // GNU __null is a pointer-width integer, not an actual pointer.
   ProgramStateRef state = Pred->getState();
Index: lib/StaticAnalyzer/Core/Environment.cpp
===
--- lib/StaticAnalyzer/Core/Environment.cpp
+++ lib/StaticAnalyzer/Core/Environment.cpp
@@ -44,6 +44,9 @@
   case Stmt::ExprWithCleanupsClass:
 E = cast(E)->getSubExpr();
 break;
+  case Stmt::ConstantExprClass:
+E = cast(E)->getSubExpr();
+break;
   case Stmt::CXXBindTemporaryExprClass:
 E = cast(E)->getSubExpr();
 break;
Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===
--- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -136,8 +136,8 @@
   E = AE->getBase();
 } else if (const auto *PE = dyn_cast(E)) {
   E = PE->getSubExpr();
-} else if (const auto *EWC = dyn_cast(E)) {
-  E = EWC->getSubExpr();
+} else if (const auto *FE = dyn_cast(E)) {
+  E = FE->getSubExpr();
 } else {
   // Other arbitrary stuff.
   break;
@@ -1494,8 +1494,8 @@
 static const Expr *peelOffOuterExpr(const Expr *Ex,
 const ExplodedNode *N) {
   Ex = Ex->IgnoreParenCasts();
-  if (const auto *EWC = dyn_cast(Ex))
-return peelOffOuterExpr(EWC->getSubExpr(), N);
+  if (const auto *FE = dyn_cast(Ex))
+return peelOffOuterExpr(FE->getSubExpr(), N);
   if (const auto *OVE = dyn_cast(Ex))
 return peelOffOuterExpr(OVE->getSourceExpr(), N);
   if (const auto *POE = dyn_cast(Ex)) {
Index: lib/StaticAnalyzer/Core/BugReporter.cpp
===
--- lib/StaticAnalyzer/Core/BugReporter.cpp
+++ lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1265,7 +1265,7 @@
 if (!S)
   break;
 
-if (isa(S) ||
+if (isa(S) ||
 isa(S) ||
 isa(S))
   continue;
Index: lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -329,9 +329,8 @@
 return;
 
   if (const Expr *E = V->getInit()) {
-while (const ExprWithCleanups *exprClean =
-dyn_cast(E))
-  E = exprClean->getSubExpr();
+while (const FullExpr *FE = dyn_cast(E))
+  E = FE->getSubExpr();
 
 // Look through transitive assignments, e.g.: