aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
AgeCommit message (Collapse)AuthorFilesLines
2024-09-09Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary ↵Martin Storsjö1-2/+1
created by aggregate initialization using a default member initializer" (#97308)" This reverts commit 45c8766973bb3bb73dd8d996231e114dcf45df9f and 049512e39d96995cb373a76cf2d009a86eaf3aab. This change triggers failed asserts on inputs like this: struct a { } constexpr b; class c { public: c(a); }; class B { public: using d = int; struct e { enum { f } g; int h; c i; d j{}; }; }; B::e k{B::e::f, int(), b}; Compiled like this: clang -target x86_64-linux-gnu -c repro.cpp clang: ../../clang/lib/CodeGen/CGExpr.cpp:3105: clang::CodeGen::LValue clang::CodeGen::CodeGenFunction::EmitDeclRefLValue(const clang::DeclRefExpr*): Assertion `(ND->isUsed(false) || !isa<VarDecl>(ND) || E->isNonOdrUse() || !E->getLocation().isValid()) && "Should not use decl without marking it used!"' failed.
2024-09-08Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by ↵yronglin1-1/+2
aggregate initialization using a default member initializer" (#97308) The PR reapply https://github.com/llvm/llvm-project/pull/92527. Implemented CWG1815 and fixed the bugs mentioned in the comments of https://github.com/llvm/llvm-project/pull/92527 and https://github.com/llvm/llvm-project/pull/87933. The reason why the original PR was reverted was that errors might occur during the rebuild. --------- Signed-off-by: yronglin <yronglin777@gmail.com>
2024-09-06[Parser][NFC] Move the core parsing of an attribute into a separate method ↵Bill Wendling1-57/+82
(#107300) Refactor attribute parsing so that the main code parsing an attribute can be called by a separate code path that doesn't start with the '__attribute' keyword.
2024-08-23Implement resource binding type prefix mismatch diagnostic infrastructure ↵Joshua Batista1-1/+2
(#97103) There are currently no diagnostics being emitted for when a resource is bound to a register with an incorrect binding type prefix. For example, a CBuffer type resource should be bound with a a binding type prefix of 'b', but if instead the prefix is 'u', no errors will be emitted. This PR implements such diagnostics. The focus of this PR is to implement both the flag setting and diagnostic emisison steps specified in the relevant spec: https://github.com/microsoft/hlsl-specs/pull/230 The relevant issue is: https://github.com/llvm/llvm-project/issues/57886 This is a continuation / refresh of this PR: https://github.com/llvm/llvm-project/pull/87578
2024-08-21[clang] Diagnose functions with too many parameters (#104833)Vlad Serebrennikov1-0/+11
This patch adds a parser check when a function declaration or function type declaration (in a function pointer declaration, for example) has too many parameters for `FunctionTypeBits::NumParams` to hold. At the moment of writing it's a 16-bit-wide bit-field, limiting the number of parameters at 65536. The check is added in the parser loop that goes over comma-separated list of function parameters. This is not the solution Aaron suggested in https://github.com/llvm/llvm-project/issues/35741#issuecomment-1638086571, because it was found out that it's quite hard to recover from this particular error in `GetFullTypeForDeclarator()`. Multiple options were tried, but all of them led to crashes down the line. I used LLVM Compile Time Tracker to ensure this does not introduce a performance regression. I believe changes are in the noise: https://llvm-compile-time-tracker.com/compare.php?from=de5ea2d122c31e1551654ff506c33df299f351b8&to=424818620766cedb2770e076ee359afeb0cc14ec&stat=instructions:u Fixes #35741
2024-08-06[clang] Fix compile-time regression from attribute arg checking change (#101768)Mike Rice1-54/+17
In 2acf77f987331c05520c5bfd849326909ffce983 code was added to use the 'full' name including syntax and scope. Instead of building up a large string for each name, add syntax and scope checks to the value expression in tablegen. There is already code to generate expressions for target specific attributes. This change refactors and adds to that code to include syntax and scope checks. The tablegen avoids generating the complicated expression unless there are two attributes using the same name, otherwise the case values will be as simple as before. Removes the currently unused attributeHasStrictIdentifierArgAtIndex function and the related tablegen.
2024-08-05[HLSL] Implement intangible AST type (#97362)Helena Kotas1-0/+13
HLSL has a set of intangible types which are described in in the [draft HLSL Specification (**[Basic.types]**)](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf): There are special implementation-defined types such as handle types, which fall into a category of standard intangible types. Intangible types are types that have no defined object representation or value representation, as such the size is unknown at compile time. A class type T is an intangible class type if it contains an base classes or members of intangible class type, standard intangible type, or arrays of such types. Standard intangible types and intangible class types are collectively called intangible types([9](https://microsoft.github.io/hlsl-specs/specs/hlsl.html#Intangible)). This PR implements one standard intangible type `__hlsl_resource_t` and sets up the infrastructure that will make it easier to add more in the future, such as samplers or raytracing payload handles. The HLSL intangible types are declared in `clang/include/clang/Basic/HLSLIntangibleTypes.def` and this file is included with related macro definition in most places that require edits when a new type is added. The new types are added as keywords and not typedefs to make sure they cannot be redeclared, and they can only be declared in builtin implicit headers. The `__hlsl_resource_t` type represents a handle to a memory resource and it is going to be used in builtin HLSL buffer types like this: template <typename T> class RWBuffer { [[hlsl::contained_type(T)]] [[hlsl::is_rov(false)]] [[hlsl::resource_class(uav)]] __hlsl_resource_t Handle; }; Part 1/3 of llvm/llvm-project#90631. --------- Co-authored-by: Justin Bogner <mail@justinbogner.com>
2024-07-30[clang] Update argument checking tablegen code to use a 'full' name (#99993)Mike Rice1-35/+79
In 92fc1eb0c1ae3813f2ac9208e2c74207aae9d23 the HLSLLoopHint attribute was added with an 'unroll' spelling. There is an existing LoopHint attribute with the same spelling. These attributes have different arguments. The tablegen used to produce checks on arguments uses only the attribute name, making it impossible to return correct info for attribute with different argument types but the same name. Improve the situation by using a 'full' name that combines the syntax, scope, and name. This allows, for example, #pragma unroll and [[unroll(x)]] to coexist correctly even with different argument types. Also fix a bug in the StrictEnumParameters tablegen. If will now correctly specify each parameter instead of only the first.
2024-07-29[Clang][Parse] Fix ambiguity with nested-name-specifiers that may ↵Krystian Stasiowski1-32/+50
declarative (#96364) Consider the following: ``` template<typename T> struct A { }; template<typename T> int A<T>::B::* f(); // error: no member named 'B' in 'A<T>' ``` Although this is clearly valid, clang rejects it because the _nested-name-specifier_ `A<T>::` is parsed as-if it was declarative, meaning, we parse it as-if it was the _nested-name-specifier_ in a redeclaration/specialization. However, we don't (and can't) know whether the _nested-name-specifier_ is declarative until we see the '`*`' token, but at that point we have already complained that `A` has no member named `B`! This patch addresses this bug by adding support for _fully_ unannotated _and_ unbounded tentative parsing, which allows for us to parse past tokens without having to cache them until we reach a point where we can guarantee to be past the construct we are disambiguating. I don't know where the approach taken here is ideal -- alternatives are welcome. However, the performance impact (as measured by llvm-compile-time-tracker (https://llvm-compile-time-tracker.com/?config=Overview&stat=instructions%3Au&remote=sdkrystian) is quite minimal (0.09%, which I plan to further improve).
2024-07-22Revert "[Clang] Implement P3034R1 Module Declarations Shouldn’t be Macros" ↵yronglin1-7/+1
(#99838) Reverts llvm/llvm-project#90574
2024-07-20[Clang] Implement P3034R1 Module Declarations Shouldn’t be Macros (#90574)yronglin1-1/+7
This PR implement [P3034R1 Module Declarations Shouldn’t be Macros](https://wg21.link/P3034R1), and refactor the convoluted state machines in module name lexical analysis. --------- Signed-off-by: yronglin <yronglin777@gmail.com> Co-authored-by: Aaron Ballman <aaron@aaronballman.com> Co-authored-by: cor3ntin <corentinjabot@gmail.com>
2024-07-09[Bounds-Safety] Add sized_by, counted_by_or_null & sized_by_or_null (#93231)Henrik G. Olsson1-4/+6
The attributes `sized_by`, `counted_by_or_null` and `sized_by_or_null` have been added as variants on `counted_by`, each with slightly different semantics. `sized_by` takes a byte size parameter instead of an element count, allowing pointees with unknown size. The `counted_by_or_null` and `sized_by_or_null` variants are equivalent to their base variants, except the pointer can be null regardless of count/size value. If the pointer is null the size is effectively 0. rdar://125400354
2024-07-09Support `guarded_by` attribute and related attributes inside C structs and ↵Pierre d'Herbemont1-5/+10
support late parsing them (#95455) This fixes #20777. This replaces #94216 which was reverted after being merged. Previously the `guarded_by`, `pt_guarded_by`, `acquired_after`, and `acquired_before` attributes were only supported inside C++ classes or top level C/C++ declaration. This patch allows these attributes to be added to struct members in C. These attributes have also now support experimental late parsing. This is off by default but can be enabled by passing `-fexperimental-late-parse-attributes`. This is useful for referring to a struct member after the annotated member. E.g. ``` struct Example { int a_value_defined_before __attribute__ ((guarded_by(a_mutex))); struct Mutex *a_mutex; }; ```
2024-06-26 [clang] Implement pointer authentication for C++ virtual functions, ↵Oliver Hunt1-1/+29
v-tables, and VTTs (#94056) Virtual function pointer entries in v-tables are signed with address discrimination in addition to declaration-based discrimination, where an integer discriminator the string hash (see `ptrauth_string_discriminator`) of the mangled name of the overridden method. This notably provides diversity based on the full signature of the overridden method, including the method name and parameter types. This patch introduces ItaniumVTableContext logic to find the original declaration of the overridden method. On AArch64, these pointers are signed using the `IA` key (the process-independent code key.) V-table pointers can be signed with either no discrimination, or a similar scheme using address and decl-based discrimination. In this case, the integer discriminator is the string hash of the mangled v-table identifier of the class that originally introduced the vtable pointer. On AArch64, these pointers are signed using the `DA` key (the process-independent data key.) Not using discrimination allows attackers to simply copy valid v-table pointers from one object to another. However, using a uniform discriminator of 0 does have positive performance and code-size implications on AArch64, and diversity for the most important v-table access pattern (virtual dispatch) is already better assured by the signing schemas used on the virtual functions. It is also known that some code in practice copies objects containing v-tables with `memcpy`, and while this is not permitted formally, it is something that may be invasive to eliminate. This is controlled by: ``` -fptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-address-discrimination ``` In addition, this provides fine-grained controls in the ptrauth_vtable_pointer attribute, which allows overriding the default ptrauth schema for vtable pointers on a given class hierarchy, e.g.: ``` [[clang::ptrauth_vtable_pointer(no_authentication, no_address_discrimination, no_extra_discrimination)]] [[clang::ptrauth_vtable_pointer(default_key, default_address_discrimination, custom_discrimination, 0xf00d)]] ``` The override is then mangled as a parametrized vendor extension: ``` "__vtptrauth" I <key> <addressDiscriminated> <extraDiscriminator> E ``` To support this attribute, this patch adds a small extension to the attribute-emitter tablegen backend. Note that there are known areas where signing is either missing altogether or can be strengthened. Some will be addressed in later changes (e.g., member function pointers, some RTTI). `dynamic_cast` in particular is handled by emitting an artificial v-table pointer load (in a way that always authenticates it) before the runtime call itself, as the runtime doesn't have enough information today to properly authenticate it. Instead, the runtime is currently expected to strip the v-table pointer. --------- Co-authored-by: John McCall <rjmccall@apple.com> Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
2024-06-12Revert "Support `guarded_by` attribute and related attributes inside C ↵Dan Liew1-117/+1
structs and support late parsing them (#94216)" This reverts commit af0d7128c8fd053d3de8af208d7d1682bc7a525a. Reverting due to likely regression: https://github.com/llvm/llvm-project/pull/94216#issuecomment-2164013300
2024-06-12Support `guarded_by` attribute and related attributes inside C structs and ↵Pierre d'Herbemont1-1/+117
support late parsing them (#94216) This fixes #20777. Previously the `guarded_by`, `pt_guarded_by`, `acquired_after`, and `acquired_before` attributes were only supported inside C++ classes or top level C/C++ declaration. This patch allows these attributes to be added to struct members in C. These attributes have also now support experimental late parsing. This is off by default but can be enabled by passing `-fexperimental-late-parse-attributes`. This is useful for referring to a struct member after the annotated member. E.g. ``` struct Example { int a_value_defined_before __attribute__ ((guarded_by(a_mutex))); struct Mutex *a_mutex; }; ``` Patch by Pierre d'Herbemont (@pdherbemont)
2024-05-27[Clang] [Sema] Diagnose unexpanded parameter packs in attributes (#93482)Sirraide1-0/+5
Call `DiagnoseUnexpandedParameterPack` when we parse an expression argument to an attribute and check for implicit code in the `CollectUnexpandedParameterPacksVisitor` so we can actually find unexpanded packs in attributes that end up applied to lambda call operators. This fixes #93269.
2024-05-23Reland #90786 ([BoundsSafety] Allow 'counted_by' attribute on pointers in ↵Dan Liew1-7/+99
structs in C) (#93121) [BoundsSafety] Reland #93121 Allow 'counted_by' attribute on pointers in structs in C (#93121) Fixes #92687. Previously the attribute was only allowed on flexible array members. This patch patch changes this to also allow the attribute on pointer fields in structs and also allows late parsing of the attribute in some contexts. For example this previously wasn't allowed: ``` struct BufferTypeDeclAttributePosition { size_t count; char* buffer __counted_by(count); // Now allowed } ``` Note the attribute is prevented on pointee types where the size isn't known at compile time. In particular pointee types that are: * Incomplete (e.g. `void`) and sizeless types * Function types (e.g. the pointee of a function pointer) * Struct types with a flexible array member This patch also introduces late parsing of the attribute when used in the declaration attribute position. For example ``` struct BufferTypeDeclAttributePosition { char* buffer __counted_by(count); // Now allowed size_t count; } ``` is now allowed but **only** when passing `-fexperimental-late-parse-attributes`. The motivation for using late parsing here is to avoid breaking the data layout of structs in existing code that want to use the `counted_by` attribute. This patch is the first use of `LateAttrParseExperimentalExt` in `Attr.td` that was introduced in a previous patch. Note by allowing the attribute on struct member pointers this now allows the possiblity of writing the attribute in the type attribute position. For example: ``` struct BufferTypeAttributePosition { size_t count; char *__counted_by(count) buffer; // Now allowed } ``` However, the attribute in this position is still currently parsed immediately rather than late parsed. So this will not parse currently: ``` struct BufferTypeAttributePosition { char *__counted_by(count) buffer; // Fails to parse size_t count; } ``` The intention is to lift this restriction in future patches. It has not been done in this patch to keep this size of this commit small. There are also several other follow up changes that will need to be addressed in future patches: * Make late parsing working with anonymous structs (see `on_pointer_anon_buf` in `attr-counted-by-late-parsed-struct-ptrs.c`). * Allow `counted_by` on more subjects (e.g. parameters, returns types) when `-fbounds-safety` is enabled. * Make use of the attribute on pointer types in code gen (e.g. for `_builtin_dynamic_object_size` and UBSan's array-bounds checks). This work is heavily based on a patch originally written by Yeoul Na. ** Differences between #93121 and this patch ** * The memory leak that caused #93121 to be reverted (see #92687) should now be fixed. See "The Memory Leak". * The fix to `pragma-attribute-supported-attributes-list.test` (originally in cef6387) has been incorporated into this patch. * A relaxation of counted_by semantics (originally in 112eadd) has been incorporated into this patch. * The assert in `Parser::DistributeCLateParsedAttrs` has been removed because that broke downstream code. * The switch statement in `Parser::ParseLexedCAttribute` has been removed in favor of using `Parser::ParseGNUAttributeArgs` which does the same thing but is more feature complete. * The `EnterScope` parameter has been plumbed through `Parser::ParseLexedCAttribute` and `Parser::ParseLexedCAttributeList`. It currently doesn't do anything but it will be needed in future commits. ** The Memory Leak ** The problem was that these lines parsed the attributes but then did nothing to free the memory ``` assert(!getLangOpts().CPlusPlus); for (auto *LateAttr : LateFieldAttrs) ParseLexedCAttribute(*LateAttr); ``` To fix this this a new `Parser::ParseLexedCAttributeList` method has been added (based on `Parser::ParseLexedAttributeList`) which does the necessary memory management. The intention is to merge these two methods together so there is just one implementation in a future patch (#93263). A more principled fixed here would be to fix the ownership of the `LateParsedAttribute` objects. In principle `LateParsedAttrList` should own its pointers exclusively and be responsible for deallocating them. Unfortunately this is complicated by `LateParsedAttribute` objects also being stored in another data structure (`LateParsedDeclarations`) as can be seen below (`LA` gets stored in two places). ``` // Handle attributes with arguments that require late parsing. LateParsedAttribute *LA = new LateParsedAttribute(this, *AttrName, AttrNameLoc); LateAttrs->push_back(LA); // Attributes in a class are parsed at the end of the class, along // with other late-parsed declarations. if (!ClassStack.empty() && !LateAttrs->parseSoon()) getCurrentClass().LateParsedDeclarations.push_back(LA); ``` this means the ownership of LateParsedAttribute objects isn't very clear. rdar://125400257
2024-05-22[Clang] Refactor `__attribute__((assume))` (#84934)Sirraide1-0/+7
This is a followup to #81014 and #84582: Before this patch, Clang would accept `__attribute__((assume))` and `[[clang::assume]]` as nonstandard spellings for the `[[omp::assume]]` attribute; this resulted in a potentially very confusing name clash with C++23’s `[[assume]]` attribute (and GCC’s `assume` attribute with the same semantics). This pr replaces every usage of `__attribute__((assume))` with `[[omp::assume]]` and makes `__attribute__((assume))` and `[[clang::assume]]` alternative spellings for C++23’s `[[assume]]`; this shouldn’t cause any problems due to differences in appertainment and because almost no-one was using this variant spelling to begin with (a use in libclc has already been changed to use a different attribute).
2024-05-22[clang][NFC] Refactor `Sema::TagUseKind` (#92689)Vlad Serebrennikov1-17/+16
This patch makes `TagUseKind` a scoped enumeration, and moves it outside of `Sema` class, making it eligible for forward declaring.
2024-05-19[Clang][HLSL] Add environment parameter to availability attribute (#89809)Helena Kotas1-1/+19
Add `environment` parameter to Clang availability attribute. The allowed values for this parameter are a subset of values allowed in the `llvm::Triple` environment component. If the `environment` parameters is present, the declared availability attribute applies only to targets with the same platform and environment. This new parameter will be initially used for annotating HLSL functions for the `shadermodel` platform because in HLSL built-in function availability can depend not just on the shader model version (mapped to `llvm::Triple::OSType`) but also on the target shader stage (mapped to `llvm::Triple::EnvironmentType`). See example in #89802 and microsoft/hlsl-specs#204 for more details. The environment parameter is currently supported only for HLSL. Fixes #89802
2024-05-19Revert "[BoundsSafety] Allow 'counted_by' attribute on pointers in structs ↵Vitaly Buka1-97/+7
in C (#90786)" Memory leak: https://lab.llvm.org/buildbot/#/builders/5/builds/43403 Issue #92687 This reverts commit 0ec3b972e58bcbcdc1bebe1696ea37f2931287c3.
2024-05-17[BoundsSafety] Allow 'counted_by' attribute on pointers in structs in C (#90786)Dan Liew1-7/+97
Previously the attribute was only allowed on flexible array members. This patch patch changes this to also allow the attribute on pointer fields in structs and also allows late parsing of the attribute in some contexts. For example this previously wasn't allowed: ``` struct BufferTypeDeclAttributePosition { size_t count; char* buffer __counted_by(count); // Now allowed } ``` Note the attribute is prevented on pointee types where the size isn't known at compile time. In particular pointee types that are: * Incomplete (e.g. `void`) and sizeless types * Function types (e.g. the pointee of a function pointer) * Struct types with a flexible array member This patch also introduces late parsing of the attribute when used in the declaration attribute position. For example ``` struct BufferTypeDeclAttributePosition { char* buffer __counted_by(count); // Now allowed size_t count; } ``` is now allowed but **only** when passing `-fexperimental-late-parse-attributes`. The motivation for using late parsing here is to avoid breaking the data layout of structs in existing code that want to use the `counted_by` attribute. This patch is the first use of `LateAttrParseExperimentalExt` in `Attr.td` that was introduced in a previous patch. Note by allowing the attribute on struct member pointers this now allows the possiblity of writing the attribute in the type attribute position. For example: ``` struct BufferTypeAttributePosition { size_t count; char *__counted_by(count) buffer; // Now allowed } ``` However, the attribute in this position is still currently parsed immediately rather than late parsed. So this will not parse currently: ``` struct BufferTypeAttributePosition { char *__counted_by(count) buffer; // Fails to parse size_t count; } ``` The intention is to lift this restriction in future patches. It has not been done in this patch to keep this size of this commit small. There are also several other follow up changes that will need to be addressed in future patches: * Make late parsing working with anonymous structs (see `on_pointer_anon_buf` in `attr-counted-by-late-parsed-struct-ptrs.c`). * Allow `counted_by` on more subjects (e.g. parameters, returns types) when `-fbounds-safety` is enabled. * Make use of the attribute on pointer types in code gen (e.g. for `_builtin_dynamic_object_size` and UBSan's array-bounds checks). This work is heavily based on a patch originally written by Yeoul Na. rdar://125400257 Co-authored-by: Dan Liew <dan@su-root.co.uk>
2024-05-17[clang] Introduce `SemaCodeCompletion` (#92311)Vlad Serebrennikov1-28/+34
This patch continues previous efforts to split `Sema` up, this time covering code completion. Context can be found in #84184. Dropping `Code` prefix from function names in `SemaCodeCompletion` would make sense, but I think this PR has enough changes already. As usual, formatting changes are done as a separate commit. Hopefully this helps with the review.
2024-05-17[clang][NFC] Remove `const_cast` from `ParseClassSpecifier`Vlad Serebrennikov1-5/+7
2024-05-13[clang] Introduce `SemaObjC` (#89086)Vlad Serebrennikov1-3/+4
This is continuation of efforts to split `Sema` up, following the example of OpenMP, OpenACC, etc. Context can be found in https://github.com/llvm/llvm-project/pull/82217 and https://github.com/llvm/llvm-project/pull/84184. I split formatting changes into a separate commit to help reviewing the actual changes.
2024-05-11[clang] Use StringRef::operator== instead of StringRef::equals (NFC) (#91844)Kazu Hirata1-1/+1
I'm planning to remove StringRef::equals in favor of StringRef::operator==. - StringRef::operator==/!= outnumber StringRef::equals by a factor of 24 under clang/ in terms of their usage. - The elimination of StringRef::equals brings StringRef closer to std::string_view, which has operator== but not equals. - S == "foo" is more readable than S.equals("foo"), especially for !Long.Expression.equals("str") vs Long.Expression != "str".
2024-05-10[Clang][Sema] access checking of friend declaration should not be delayed ↵Qizhi Hu1-2/+5
(#91430) attempt to fix https://github.com/llvm/llvm-project/issues/12361 Consider this example: ```cpp class D { class E{ class F{}; friend void foo(D::E::F& q); }; friend void foo(D::E::F& q); }; void foo(D::E::F& q) {} ``` The first friend declaration of foo is correct. After that, the second friend declaration delayed access checking and set its previous declaration to be the first one. When doing access checking of `F`(which is private filed of `E`), we put its canonical declaration(the first friend declaration) into `EffectiveContext.Functions`. Actually, we are still checking the first one. This is incorrect due to the delayed checking. Creating a new scope to indicate we are parsing a friend declaration and doing access checking in time.
2024-05-09[Clang] Fix P2564 handling of variable initializers (#89565)Daniel M. Katz1-11/+10
The following program produces a diagnostic in Clang and EDG, but compiles correctly in GCC and MSVC: ```cpp #include <vector> consteval std::vector<int> fn() { return {1,2,3}; } constexpr int a = fn()[1]; ``` Clang's diagnostic is as follows: ```cpp <source>:6:19: error: call to consteval function 'fn' is not a constant expression 6 | constexpr int a = fn()[1]; | ^ <source>:6:19: note: pointer to subobject of heap-allocated object is not a constant expression /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.1/../../../../include/c++/14.0.1/bits/allocator.h:193:31: note: heap allocation performed here 193 | return static_cast<_Tp*>(::operator new(__n)); | ^ 1 error generated. Compiler returned: 1 ``` Based on my understanding of [`[dcl.constexpr]/6`](https://eel.is/c++draft/dcl.constexpr#6): > In any constexpr variable declaration, the full-expression of the initialization shall be a constant expression It seems to me that GCC and MSVC are correct: the initializer `fn()[1]` does not evaluate to an lvalue referencing a heap-allocated value within the `vector` returned by `fn()`; it evaluates to an lvalue-to-rvalue conversion _from_ that heap-allocated value. This PR turns out to be a bug fix on the implementation of [P2564R3](https://wg21.link/p2564r3); as such, it only applies to C++23 and later. The core problem is that the definition of a constant-initialized variable ([`[expr.const/2]`](https://eel.is/c++draft/expr.const#2)) is contingent on whether the initializer can be evaluated as a constant expression: > A variable or temporary object o is _constant-initialized_ if [...] the full-expression of its initialization is a constant expression when interpreted as a _constant-expression_, [...] That can't be known until we've finished parsing the initializer, by which time we've already added immediate invocations and consteval references to the current expression evaluation context. This will have the effect of evaluating said invocations as full expressions when the context is popped, even if they're subexpressions of a larger constant expression initializer. If, however, the variable _is_ constant-initialized, then its initializer is [manifestly constant-evaluated](https://eel.is/c++draft/expr.const#20): > An expression or conversion is _manifestly constant-evaluated_ if it is [...] **the initializer of a variable that is usable in constant expressions or has constant initialization** [...] which in turn means that any subexpressions naming an immediate function are in an [immediate function context](https://eel.is/c++draft/expr.const#16): > An expression or conversion is in an immediate function context if it is potentially evaluated and either [...] it is a **subexpression of a manifestly constant-evaluated expression** or conversion and therefore _are not to be considered [immediate invocations](https://eel.is/c++draft/expr.const#16) or [immediate-escalating expressions](https://eel.is/c++draft/expr.const#17) in the first place_: > An invocation is an _immediate invocation_ if it is a potentially-evaluated explicit or implicit invocation of an immediate function and **is not in an immediate function context**. > An expression or conversion is _immediate-escalating_ if **it is not initially in an immediate function context** and [...] The approach that I'm therefore proposing is: 1. Create a new expression evaluation context for _every_ variable initializer (rather than only nonlocal ones). 2. Attach initializers to `VarDecl`s _prior_ to popping the expression evaluation context / scope / etc. This sequences the determination of whether the initializer is in an immediate function context _before_ any contained immediate invocations are evaluated. 3. When popping an expression evaluation context, elide all evaluations of constant invocations, and all checks for consteval references, if the context is an immediate function context. Note that if it could be ascertained that this was an immediate function context at parse-time, we [would never have registered](https://github.com/llvm/llvm-project/blob/760910ddb918d77e7632be1678f69909384d69ae/clang/lib/Sema/SemaExpr.cpp#L17799) these immediate invocations or consteval references in the first place. Most of the test changes previously made for this PR are now reverted and passing as-is. The only test updates needed are now as follows: - A few diagnostics in `consteval-cxx2a.cpp` are updated to reflect that it is the `consteval tester::tester` constructor, not the more narrow `make_name` function call, which fails to be evaluated as a constant expression. - The reclassification of `warn_impcast_integer_precision_constant` as a compile-time diagnostic adds a (somewhat duplicative) warning when attempting to define an enum constant using a narrowing conversion. It also, however, retains the existing diagnostics which @erichkeane (rightly) objected to being lost from an earlier revision of this PR. --------- Co-authored-by: cor3ntin <corentinjabot@gmail.com>
2024-04-30Reapply "[Clang][Sema] Diagnose class member access expressions naming ↵Krystian Stasiowski1-1/+1
non-existent members of the current instantiation prior to instantiation in the absence of dependent base classes (#84050)" (#90152) Reapplies #84050, addressing a bug which cases a crash when an expression with the type of the current instantiation is used as the _postfix-expression_ in a class member access expression (arrow form).
2024-04-30[Clang][Sema][Parse] Delay parsing of noexcept-specifiers in friend function ↵Krystian Stasiowski1-6/+14
declarations (#90517) According to [class.mem.general] p8: > A complete-class context of a class (template) is a > - function body, > - default argument, > - default template argument, > - _noexcept-specifier_, or > - default member initializer > > within the member-specification of the class or class template. When testing #90152, it came to my attention that we do _not_ consider the _noexcept-specifier_ of a friend function declaration to be a complete-class context (something which the Microsoft standard library depends on). Although a comment states that this is "consistent with what other implementations do", the only other implementation that exhibits this behavior is GCC (MSVC and EDG both late-parse the _noexcept-specifier_). This patch changes _noexcept-specifiers_ of friend function declarations to be late parsed, which is in agreement with the standard & majority of implementations. Pre-#90152, our existing implementation falls "in between" the implementation consensus: within non-template classes, we would not find latter declared members (qualified and unqualified), while within class templates we would not find latter declared member when named with a unqualified name, we would find members named with a qualified name (even when lookup context is the current instantiation). Therefore, this _shouldn't_ be a breaking change -- any code that didn't compile will continue to not compile (since a _noexcept-specifier_ is not part of the deduction substitution loci (see [temp.deduct.general] p7), and any code which did compile should continue to do so.
2024-04-29[Attributes] Support Attributes being declared as supporting an experimental ↵Dan Liew1-6/+34
late parsing mode "extension" (#88596) This patch changes the `LateParsed` field of `Attr` in `Attr.td` to be an instantiation of the new `LateAttrParseKind` class. The instation can be one of the following: * `LateAttrParsingNever` - Corresponds with the false value of `LateParsed` prior to this patch (the default for an attribute). * `LateAttrParseStandard` - Corresponds with the true value of `LateParsed` prior to this patch. * `LateAttrParseExperimentalExt` - A new mode described below. `LateAttrParseExperimentalExt` is an experimental extension to `LateAttrParseStandard`. Essentially this allows `Parser::ParseGNUAttributes(...)` to distinguish between these cases: 1. Only `LateAttrParseExperimentalExt` attributes should be late parsed. 2. Both `LateAttrParseExperimentalExt` and `LateAttrParseStandard` attributes should be late parsed. Callers (and indirect callers) of `Parser::ParseGNUAttributes(...)` indicate the desired behavior by setting a flag in the `LateParsedAttrList` object that is passed to the function. In addition to the above, a new driver and frontend flag (`-fexperimental-late-parse-attributes`) with a corresponding LangOpt (`ExperimentalLateParseAttributes`) is added that changes how `LateAttrParseExperimentalExt` attributes are parsed. * When the flag is disabled (default), in cases where only `LateAttrParsingExperimentalOnly` late parsing is requested, the attribute will be parsed immediately (i.e. **NOT** late parsed). This allows the attribute to act just like a `LateAttrParseStandard` attribute when the flag is disabled. * When the flag is enabled, in cases where only `LateAttrParsingExperimentalOnly` late parsing is requested, the attribute will be late parsed. The motivation behind this change is to allow the new `counted_by` attribute (part of `-fbounds-safety`) to support late parsing but **only** when `-fexperimental-late-parse-attributes` is enabled. This attribute needs to support late parsing to allow it to refer to fields later in a struct definition (or function parameters declared later). However, there isn't a precedent for supporting late attribute parsing in C so this flag allows the new behavior to exist in Clang but not be on by default. This behavior was requested as part of the `-fbounds-safety` RFC process (https://discourse.llvm.org/t/rfc-enforcing-bounds-safety-in-c-fbounds-safety/70854/68). This patch doesn't introduce any uses of `LateAttrParseExperimentalExt`. This will be added for the `counted_by` attribute in a future patch (https://github.com/llvm/llvm-project/pull/87596). A consequence is the new behavior added in this patch is not yet testable. Hence, the lack of tests covering the new behavior. rdar://125400257
2024-04-28[Clang] Implement C++26 Attributes for Structured Bindings (P0609R3) (#89906)cor3ntin1-10/+31
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0609r3.pdf We support this feature in all language mode. maybe_unused applied to a binding makes the whole declaration unused.
2024-04-26Revert "[Clang][Sema] Diagnose class member access expressions naming ↵Pranav Kant1-1/+1
non-existent members of the current instantiation prior to instantiation in the absence of dependent base classes (#84050)" This reverts commit a8fd0d029dca7d17eee72d0445223c2fe1ee7758.
2024-04-25[Clang][Sema] Diagnose class member access expressions naming non-existent ↵Krystian Stasiowski1-1/+1
members of the current instantiation prior to instantiation in the absence of dependent base classes (#84050) Consider the following: ```cpp template<typename T> struct A { auto f() { return this->x; } }; ``` Although `A` has no dependent base classes and the lookup context for `x` is the current instantiation, we currently do not diagnose the absence of a member `x` until `A<T>::f` is instantiated. This patch moves the point of diagnosis for such expressions to occur at the point of definition (i.e. prior to instantiation).
2024-04-22[NFC] Rename hlsl semantics to hlsl annotations (#89309)Joshua Batista1-3/+3
The attribute name "HLSLSemantics" is confusing, because semantics aren't always the annotation that are applied to specific variables. The name for this attribute needs to be less specific. This PR changes the attribute name from HLSLSemantic to HLSLAnnotation, and changes the associated function and variable names to support this conceptual change. The HLSLAnnotation attribute will never be output in ast-dump due to it being parsed for the attribute that it represents. There is no functional change, so there are no accompanying tests.
2024-04-17[Clang][Parse] Diagnose requires expressions with explicit object parameters ↵Krystian Stasiowski1-1/+14
(#88974) Clang currently allows the following: ``` auto x = requires (this int) { true; }; ``` This patch addresses that.
2024-04-17[clang][NFC] Move `Sema::SkipBodyInfo` into namespace scopeVlad Serebrennikov1-1/+1
This makes it forward-declarable, and needed from splitting `Sema` up.
2024-04-16[clang] Introduce `SemaOpenMP` (#88642)Vlad Serebrennikov1-1/+2
This patch moves OpenMP-related entities out of `Sema` to a newly created `SemaOpenMP` class. This is a part of the effort to split `Sema` up, and follows the recent example of CUDA, OpenACC, SYCL, HLSL. Additional context can be found in https://github.com/llvm/llvm-project/pull/82217, https://github.com/llvm/llvm-project/pull/84184, https://github.com/llvm/llvm-project/pull/87634.
2024-04-15[Clang] Refactor implementation of "Lifetime extension in range-based for ↵yronglin1-4/+0
loops" (#87930) This PR remove `InMaterializeTemporaryObjectContext` , because it's redundant, materialize non-cv void prvalue temporaries in discarded expressions can only appear under lifetime-extension context. Signed-off-by: yronglin <yronglin777@gmail.com>
2024-04-14[Clang] [C++26] Implement P2573R2: `= delete("should have a reason");` (#86526)Sirraide1-0/+1
This implements support for the `= delete("message")` syntax that was only just added to C++26 ([P2573R2](https://isocpp.org/files/papers/P2573R2.html#proposal-scope)).
2024-04-13[clang] Introduce `SemaCUDA` (#88559)Vlad Serebrennikov1-1/+3
This patch moves CUDA-related `Sema` function into new `SemaCUDA` class, following the recent example of SYCL, OpenACC, and HLSL. This is a part of the effort to split Sema. Additional context can be found in https://github.com/llvm/llvm-project/pull/82217, https://github.com/llvm/llvm-project/pull/84184, https://github.com/llvm/llvm-project/pull/87634.
2024-04-11[NFC][Clang] Improve const correctness for IdentifierInfo (#79365)Bill Wendling1-1/+1
The IdentifierInfo isn't typically modified. Use 'const' wherever possible.
2024-03-20Turn 'counted_by' into a type attribute and parse it into ↵Yeoul Na1-0/+90
'CountAttributedType' (#78000) In `-fbounds-safety`, bounds annotations are considered type attributes rather than declaration attributes. Constructing them as type attributes allows us to extend the attribute to apply nested pointers, which is essential to annotate functions that involve out parameters: `void foo(int *__counted_by(*out_count) *out_buf, int *out_count)`. We introduce a new sugar type to support bounds annotated types, `CountAttributedType`. In order to maintain extra data (the bounds expression and the dependent declaration information) that is not trackable in `AttributedType` we create a new type dedicate to this functionality. This patch also extends the parsing logic to parse the `counted_by` argument as an expression, which will allow us to extend the model to support arguments beyond an identifier, e.g., `__counted_by(n + m)` in the future as specified by `-fbounds-safety`. This also adjusts `__bdos` and array-bounds sanitizer code that already uses `CountedByAttr` to check `CountAttributedType` instead to get the field referred to by the attribute.
2024-03-07[clang] Upstream visionOS Availability & DarwinSDKInfo APIs (#84279)Cyndy Ishida1-1/+4
Admittedly a bit awkward, `visionos` is the correct and accepted spelling for annotating availability for xrOS target triples. This patch detects errors and handles cases when `xros` is mistakenly passed. In addition, add APIs for introduced/deprecated/obsoleted versioning in DarwinSDKInfo mappings.
2024-03-07[clang-repl] Names declared in if conditions and for-init statements are ↵Stefan Gränitz1-8/+16
local to the inner context (#84150) Make TopLevelStmtDecl a DeclContext so that variables defined in statements are attached to the TopLevelDeclContext. This fixes redefinition errors from variables declared in if conditions and for-init statements. These must be local to the inner context (C++ 3.3.2p4), but they had generated definitions on global scope instead. This PR makes the TopLevelStmtDecl looking more like a FunctionDecl and that's fine because the FunctionDecl is very close in terms of semantics. Additionally, ActOnForStmt() requires a CompoundScope when processing a NullStmt body. --------- Co-authored-by: Vassil Vassilev <v.g.vassilev@gmail.com>
2024-03-06[C23] Implement N3018: The constexpr specifier for object definitions (#73099)Mariya Podchishchaeva1-0/+2
The implementation mostly reuses C++ code paths where possible, including narrowing check in order to provide diagnostic messages in case initializer for constexpr variable is not exactly representable in target type. The following won't work due to lack of support for other features: - Diagnosing of underspecified declarations involving constexpr - Constexpr attached to compound literals Also due to lack of support for char8_t some of examples with utf-8 strings don't work properly. Fixes https://github.com/llvm/llvm-project/issues/64742
2024-03-04Fix null-deref thanks to an attribute on a global declarator chunk (#83611)Erich Keane1-1/+1
This was reported (sort of) in a PR: #77703. The problem is that a declarator 'owns' an attributes allocation via an `AttributePool`. However, this example tries to copy a DeclaratorChunk from one Declarator to another, so when the temporary Declarator goes out of scope, it deletes the attribute it has tried to pass on via the chunk. This patch ensures that we copy the 'ownership' of the attribute correctly, and adds an assert to catch any other casess where this happens. Additionally, this was put in as a bug report, so this Fixes #83611
2024-02-18[clang] Differentiate between identifier and string EnumArgument (#68550)Sergei Barannikov1-2/+2
EnumArgument may be a string or an identifier. If it is a string, it should be parsed as unevaluated string literal. Add IsString flag to EnumArgument so that the parser can choose the correct parsing method. Target-specific attributes that share spelling may have different attribute "prototypes". For example, ARM's version of "interrupt" attribute accepts a string enum, while MSP430's version accepts an unsigned integer. Adjust ClangAttrEmitter so that the generated `attributeStringLiteralListArg` returns the correct mask depending on target triple. It is worth noting that even after this change some string arguments are still parsed as identifiers or, worse, as expressions. This is because of some special logic in `ParseAttributeArgsCommon`. Fixing it is out of scope of this patch.
2024-02-16[C11] Diagnose C11 keywords as being incompatible w/earlier standards (#82015)Aaron Ballman1-11/+5
Our usual pattern when issuing an extension warning is to also issue a default-off diagnostic about the keywords not being compatible with standards before a certain point. This adds those diagnostics for C11 keywords.