1283 Commits

Author SHA1 Message Date
Sirraide
10c6ebc427
Reapply "[Clang] [NFC] Introduce a helper for emitting compatibility diagnostics (#132348)" (#134043)
This reapplies #132348 with a fix to the python bindings tests, reverting
076397ff32.
2025-04-02 10:40:05 +02:00
Sirraide
076397ff32
Revert "[Clang] [NFC] Introduce a helper for emitting compatibility diagnostics" (#134036)
Reverts llvm/llvm-project#132348

Some tests are failing and I still need to figure out what is going on
here.
2025-04-02 08:29:05 +02:00
Sirraide
9d06e0879b
[Clang] [NFC] Introduce a helper for emitting compatibility diagnostics (#132348)
This is a follow-up to #132129.

Currently, only `Parser` and `SemaBase` get a `DiagCompat()` helper; I’m
planning to keep refactoring compatibility warnings and add more helpers
to other classes as needed. I also refactored a single parser compat
warning just to make sure everything works properly when diagnostics
across multiple components (i.e. Sema and Parser in this case) are
involved.
2025-04-02 08:06:29 +02:00
erichkeane
79079c9469 [OpenACC] Finish implementing 'routine' AST/Sema.
This is the last item of the OpenACC 3.3 spec. It includes the
implicit-name version of 'routine', plus significant refactorings to
make the two work together.  The implicit name version is represented as
an attribute on the function call. This patch also implements the
clauses for the implicit-name version, as well as the A.3.4 warning.
2025-03-21 08:57:54 -07:00
cor3ntin
baef6fadbf
[Clang] Increase the default expression nesting limit (#132021)
This iterates on #104717 (which we had to revert)

In a bid to increase our chances of success, we try to avoid blowing up
the stack by

-  Using `runWithSufficientStackSpace` in ParseCompoundStatement
-  Reducing the size of `StmtVector` a bit
-  Reducing the size of `DeclsInGroup` a bit
- Removing a few `ParsedAttributes` from the stacks in places where they
are not strictly necessary. `ParsedAttributes` is a _huge_ object

On a 64 bits system, the following stack size reductions are observed

```
ParseStatementOrDeclarationAfterAttributes:  344 -> 264
ParseStatementOrDeclaration: 520 -> 376
ParseCompoundStatementBody: 1080 -> 1016
ParseDeclaration: 264 -> 120
```

Fixes #94728
2025-03-19 15:16:38 +01:00
Chris B
a7d5b3f711
[HLSL] Disallow virtual inheritance and functions (#127346)
This PR disallows virtual inheritance and virtual functions in HLSL.
2025-03-09 12:18:44 -05:00
Michael Jabbour
180f8032f0
[clang] Fix ASTWriter crash after merging named enums (#114240)
Clang already removes parsed enumerators when merging typedefs to
anonymous enums. This is why the following example decl used to be
handled correctly while merging, and ASTWriter behaves as expected:

```c
typedef enum { Val } AnonEnum;
```
However, the mentioned mechanism didn't handle named enums. This leads
to stale declarations in `IdResolver`, causing an assertion violation in
ASTWriter ``Assertion `DeclIDs.contains(D) && "Declaration not
emitted!"' failed`` when a module is being serialized with the following
example merged enums:

```c
typedef enum Enum1 { Val_A } Enum1;
enum Enum2 { Val_B };
```

The PR applies the same mechanism in the named enums case.

Additionally, I dropped the call to
`getLexicalDeclContext()->removeDecl` as it was causing a wrong
odr-violation diagnostic with anonymous enums.

Might be easier to to review commit by commit. Any feedback is
appreciated.

### Context

This fixes frontend crashes that were encountered when certain
Objective-C modules are included on Xcode 16. For example, by running
`CC=/path/to/clang-19 xcodebuild clean build` on a project that contains
the following Objective-C file:

```c
#include <os/atomic.h>

int main() {
  return memory_order_relaxed;
}
```
This crashes the parser in release, when ASTReader tries to load the
enumerator declaration.
2025-03-07 11:02:19 +01:00
Vipul Cariappa
4ac68ba07d
[clang-repl] fix error recovery while parsing completely fails (#127087)
Fixes the following crash in clang-repl

```c++
clang-repl> try { throw 1; } catch { 0; }
In file included from <<< inputs >>>:1:
input_line_1:1:23: error: expected '('
    1 | try { throw 1; } catch { 0; }
      |                       ^
      |                       (
clang-repl: /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/AST/DeclBase.cpp:1757: void clang::DeclContext::addHiddenDecl(clang::Decl*): Assertion `D->getLexicalDeclContext() == this && "Decl inserted into wrong lexical context"' failed.
 #0 0x000059b28459e6da llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/llvm/lib/Support/Unix/Signals.inc:804:22
 #1 0x000059b28459eaed PrintStackTraceSignalHandler(void*) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/llvm/lib/Support/Unix/Signals.inc:880:1
 #2 0x000059b28459bf7f llvm::sys::RunSignalHandlers() /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/llvm/lib/Support/Signals.cpp:105:20
 #3 0x000059b28459df8e SignalHandler(int, siginfo_t*, void*) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/llvm/lib/Support/Unix/Signals.inc:418:13
 #4 0x000077cdf444ea50 (/usr/lib/libc.so.6+0x42a50)
 #5 0x000077cdf44aee3b pthread_kill (/usr/lib/libc.so.6+0xa2e3b)
 #6 0x000077cdf444e928 raise (/usr/lib/libc.so.6+0x42928)
 #7 0x000077cdf443156c abort (/usr/lib/libc.so.6+0x2556c)
 #8 0x000077cdf44314d2 __assert_perror_fail (/usr/lib/libc.so.6+0x254d2)
 #9 0x000077cdf4444c56 (/usr/lib/libc.so.6+0x38c56)
#10 0x000059b28495bfc4 clang::DeclContext::addHiddenDecl(clang::Decl*) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/AST/DeclBase.cpp:1759:3
#11 0x000059b28495c0f5 clang::DeclContext::addDecl(clang::Decl*) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/AST/DeclBase.cpp:1785:37
#12 0x000059b28773cc2a clang::Sema::ActOnStartTopLevelStmtDecl(clang::Scope*) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/Sema/SemaDecl.cpp:20302:18
#13 0x000059b286f1efdf clang::Parser::ParseTopLevelStmtDecl() /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/Parse/ParseDecl.cpp:6024:62
#14 0x000059b286ef18ee clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/Parse/Parser.cpp:1065:35
#15 0x000059b286ef0702 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/Parse/Parser.cpp:758:36
#16 0x000059b28562dff2 clang::IncrementalParser::ParseOrWrapTopLevelDecl() /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/Interpreter/IncrementalParser.cpp:66:36
#17 0x000059b28562e5b7 clang::IncrementalParser::Parse(llvm::StringRef) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/Interpreter/IncrementalParser.cpp:132:8
#18 0x000059b28561832b clang::Interpreter::Parse(llvm::StringRef) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/Interpreter/Interpreter.cpp:570:8
#19 0x000059b285618cbd clang::Interpreter::ParseAndExecute(llvm::StringRef, clang::Value*) /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/lib/Interpreter/Interpreter.cpp:649:8
#20 0x000059b2836f9343 main /home/vipul-cariappa/Documents/Workspace/cpp-py/llvms/llvm-project-a/clang/tools/clang-repl/ClangRepl.cpp:255:59
#21 0x000077cdf443388e (/usr/lib/libc.so.6+0x2788e)
#22 0x000077cdf443394a __libc_start_main (/usr/lib/libc.so.6+0x2794a)
#23 0x000059b2836f7965 _start (./bin/clang-repl+0x73b8965)
fish: Job 1, './bin/clang-repl' terminated by signal SIGABRT (Abort)
```

With this change:
```c++
clang-repl> try { throw 1; } catch { 0; }
In file included from <<< inputs >>>:1:
input_line_1:1:23: error: expected '('
    1 | try { throw 1; } catch { 0; }
      |                       ^
      |                       (
error: Parsing failed.
clang-repl> 1;
clang-repl> %quit
```
2025-02-14 08:34:18 +01:00
Jason Rice
abc8812df0
[Clang][P1061] Add stuctured binding packs (#121417)
This is an implementation of P1061 Structure Bindings Introduce a Pack
without the ability to use packs outside of templates. There is a couple
of ways the AST could have been sliced so let me know what you think.
The only part of this change that I am unsure of is the
serialization/deserialization stuff. I followed the implementation of
other Exprs, but I do not really know how it is tested. Thank you for
your time considering this.

---------

Co-authored-by: Yanzuo Liu <zwuis@outlook.com>
2025-01-29 21:43:52 +01:00
Maksim Ivanov
41a94de75c
[clang] Refactor attr diagnostics to use %select (#122473)
A cleanup follow-up to #118501 and #118567.
2025-01-13 13:42:22 +01:00
Maksim Ivanov
6b12272353
[clang] Informative error for lifetimebound in decl-spec (#118567)
Emit a bit more informative error when the `[[clang::lifetimebound]]`
attribute is wrongly appearing on a decl-spec:

```
'lifetimebound' attribute only applies to parameters and implicit
object parameters
```

instead of:

```
'lifetimebound' attribute cannot be applied to types
```

The new error is also consistent with the diagnostic emitted when the
attribute is misplaced in other parts of a declarator.
2025-01-10 14:16:59 +01:00
antangelo
54fcf3ec26
[clang] Implement P3176R1: The Oxford variadic comma (#117524)
Emit a deprecation warning when a variadic parameter in a
parameter-declaration-clause is not preceded by a comma for C++26.
2024-12-02 03:53:55 -05:00
Kazu Hirata
834dfd2315
[Parse] Remove ParseDiagnostic.h (#116496)
This patch removes clang/Parse/ParseDiagnostic.h because it just
forwards to clang/Basic/DiagnosticParse.h.
2024-11-18 07:19:33 -08:00
Jay Foad
4dd55c567a
[clang] Use {} instead of std::nullopt to initialize empty ArrayRef (#109399)
Follow up to #109133.
2024-10-24 10:23:40 +01:00
c8ef
679be52709
[Clang][NFC] Consolidate the parameter check for the requires expression parameter. (#110773)
This patch is a follow-up to #109831. In the discussion, we agreed that
having parameter checks scattered across different areas isn't ideal.
Therefore, I suggest merging the check from #88974 into the void
parameter check. This change won't impact functionality and will enhance
maintainability.
2024-10-02 12:01:31 +08:00
Mariya Podchishchaeva
a9d9b0a03d
[clang][C23] Claim N3030 Enhancements to Enumerations supported (#107260)
Clang already implemented functionality as an extension.
2024-09-18 16:05:23 +02:00
yronglin
060137038a
Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#108039)
The PR reapply https://github.com/llvm/llvm-project/pull/97308. 

- Implement [CWG1815](https://wg21.link/CWG1815): Support lifetime
extension of temporary created by aggregate initialization using a
default member initializer.

- Fix crash that introduced in
https://github.com/llvm/llvm-project/pull/97308. In
`InitListChecker::FillInEmptyInitForField`, when we enter
rebuild-default-init context, we copy all the contents of the parent
context to the current context, which will cause the `MaybeODRUseExprs`
to be lost. But we don't need to copy the entire context, only the
`DelayedDefaultInitializationContext` was required, which is used to
build `SourceLocExpr`, etc.

---------

Signed-off-by: yronglin <yronglin777@gmail.com>
2024-09-12 06:29:48 +08:00
Martin Storsjö
cca54e347a Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary 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-09 15:09:45 +03:00
yronglin
45c8766973
Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by 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-08 22:36:49 +08:00
Bill Wendling
7815abec16
[Parser][NFC] Move the core parsing of an attribute into a separate method (#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-09-06 21:08:33 +00:00
Joshua Batista
ebc4a66e9b
Implement resource binding type prefix mismatch diagnostic infrastructure (#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-23 10:47:05 -07:00
Vlad Serebrennikov
281d17840c
[clang] Diagnose functions with too many parameters (#104833)
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-21 17:38:24 +04:00
Mike Rice
6250313291
[clang] Fix compile-time regression from attribute arg checking change (#101768)
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-06 08:28:56 -07:00
Helena Kotas
52956b0f70
[HLSL] Implement intangible AST type (#97362)
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-08-05 10:50:34 -07:00
Mike Rice
2acf77f987
[clang] Update argument checking tablegen code to use a 'full' name (#99993)
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-30 10:07:16 -07:00
Krystian Stasiowski
708a9a06cb
[Clang][Parse] Fix ambiguity with nested-name-specifiers that may 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-29 14:01:00 -04:00
yronglin
c91e85278c
Revert "[Clang] Implement P3034R1 Module Declarations Shouldn’t be Macros" (#99838)
Reverts llvm/llvm-project#90574
2024-07-22 13:16:51 +08:00
yronglin
e77a01d79a
[Clang] Implement P3034R1 Module Declarations Shouldn’t be Macros (#90574)
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-20 20:41:00 +08:00
Henrik G. Olsson
e22ebee5a3
[Bounds-Safety] Add sized_by, counted_by_or_null & sized_by_or_null (#93231)
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-09 13:58:01 -07:00
Pierre d'Herbemont
c8ba5562e5
Support guarded_by attribute and related attributes inside C structs and 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-07-09 15:08:11 +01:00
Oliver Hunt
1b8ab2f089
[clang] Implement pointer authentication for C++ virtual functions, 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-26 18:35:10 -07:00
Dan Liew
c9d580033f Revert "Support guarded_by attribute and related attributes inside C 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-12 15:43:12 -07:00
Pierre d'Herbemont
af0d7128c8
Support guarded_by attribute and related attributes inside C structs and 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-06-12 11:20:05 -07:00
Sirraide
4b5e0a1d12
[Clang] [Sema] Diagnose unexpanded parameter packs in attributes (#93482)
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-27 18:17:07 +02:00
Dan Liew
29189738b8
Reland #90786 ([BoundsSafety] Allow 'counted_by' attribute on pointers in 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-23 18:35:24 -07:00
Sirraide
c44fa3e8a9
[Clang] Refactor __attribute__((assume)) (#84934)
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 17:58:48 +02:00
Vlad Serebrennikov
3a913d30be
[clang][NFC] Refactor Sema::TagUseKind (#92689)
This patch makes `TagUseKind` a scoped enumeration, and moves it outside
of `Sema` class, making it eligible for forward declaring.
2024-05-22 02:07:28 +04:00
Helena Kotas
3f33c4c14e
[Clang][HLSL] Add environment parameter to availability attribute (#89809)
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-19 10:46:12 -07:00
Vitaly Buka
6447abe067 Revert "[BoundsSafety] Allow 'counted_by' attribute on pointers in structs in C (#90786)"
Memory leak: https://lab.llvm.org/buildbot/#/builders/5/builds/43403

Issue #92687

This reverts commit 0ec3b972e58bcbcdc1bebe1696ea37f2931287c3.
2024-05-19 05:44:40 -07:00
Dan Liew
0ec3b972e5
[BoundsSafety] Allow 'counted_by' attribute on pointers in structs in C (#90786)
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 12:07:40 -07:00
Vlad Serebrennikov
874f511ae7
[clang] Introduce SemaCodeCompletion (#92311)
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 20:55:37 +04:00
Vlad Serebrennikov
d3d5a30021 [clang][NFC] Remove const_cast from ParseClassSpecifier 2024-05-17 16:41:20 +03:00
Vlad Serebrennikov
31a203fa8a
[clang] Introduce SemaObjC (#89086)
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-13 23:37:59 +04:00
Kazu Hirata
deffae5da1
[clang] Use StringRef::operator== instead of StringRef::equals (NFC) (#91844)
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-11 11:38:52 -07:00
Qizhi Hu
200f3bd395
[Clang][Sema] access checking of friend declaration should not be delayed (#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-10 20:14:08 +08:00
Daniel M. Katz
443377a9d1
[Clang] Fix P2564 handling of variable initializers (#89565)
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](760910ddb9/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-05-09 09:22:11 +02:00
Krystian Stasiowski
8009bbec59
Reapply "[Clang][Sema] Diagnose class member access expressions naming 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 14:25:09 -04:00
Krystian Stasiowski
f061a395ff
[Clang][Sema][Parse] Delay parsing of noexcept-specifiers in friend function 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-30 14:23:02 -04:00
Dan Liew
b1867e18c3
[Attributes] Support Attributes being declared as supporting an experimental 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-29 18:37:47 -07:00
cor3ntin
6dd90616c4
[Clang] Implement C++26 Attributes for Structured Bindings (P0609R3) (#89906)
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-28 20:25:44 +02:00