[PATCH] D53780: Fix bitcast to address space cast for coerced load/stores
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"
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
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
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
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.: