2485 Commits

Author SHA1 Message Date
Timm Baeder
cfe26358e3
Reapply "[clang] Avoid re-evaluating field bitwidth" (#122289) 2025-01-11 07:12:37 +01:00
Timm Bäder
59bdea24b0 Revert "[clang] Avoid re-evaluating field bitwidth (#117732)"
This reverts commit 81fc3add1e627c23b7270fe2739cdacc09063e54.

This breaks some LLDB tests, e.g.
SymbolFile/DWARF/x86/no_unique_address-with-bitfields.cpp:

lldb: ../llvm-project/clang/lib/AST/Decl.cpp:4604: unsigned int clang::FieldDecl::getBitWidthValue() const: Assertion `isa<ConstantExpr>(getBitWidth())' failed.
2025-01-08 15:09:52 +01:00
Timm Baeder
81fc3add1e
[clang] Avoid re-evaluating field bitwidth (#117732)
Save the bitwidth value as a `ConstantExpr` with the value set. Remove
the `ASTContext` parameter from `getBitWidthValue()`, so the latter
simply returns the value from the `ConstantExpr` instead of
constant-evaluating the bitwidth expression every time it is called.
2025-01-08 14:45:19 +01:00
jijjijj
9f1e9f682d
[C++20][modules] Fix std::initializer_list recognition if it's exported out of a module (#118537)
If the std::initializer_list is exported out of module, its
`DeclContext` is not a namespace as `Sema::isStdInitializerList`
expects, but an `Decl::Kind::Export` and only its parent is a namespace.
So this commit makes `Sema::isStdInitializerList` account for that.

I'm really new to clang so I'm not 100% sure that was the issue, it
seems so and it fixes compilation. Also I probably need to add tests but
I'd like someone to approve the idea first.

Fixes https://github.com/llvm/llvm-project/issues/118218
2024-12-12 09:38:47 +08:00
yronglin
740861d69c
[clang] Fix a crash issue that caused by handling of fields with initializers in nested anonymous unions (#113049)
Fixes: https://github.com/llvm/llvm-project/issues/112560

This PR create an RecoveryExpr for invalid in-class-initializer.

---------

Signed-off-by: yronglin <yronglin777@gmail.com>
2024-12-10 20:56:52 +08:00
Chris White
d457100a81
[Clang] Fix -Wunused-private-field false negative with defaulted comparison operators (#116871)
Fix -Wunused-private-field incorrectly suppressing warnings for friend
defaulted comparison operators. The warning should only be suppressed
when the defaulted comparison is a class member function.

Fixes #116270
2024-12-05 16:32:48 +01:00
Oleksandr T.
4ad4d34a22
Revert [Clang] prevent errors for deduction guides using deduced type aliases (#118165)
Reverts https://github.com/llvm/llvm-project/pull/117450

---

Revert https://github.com/llvm/llvm-project/pull/117450 because the
prior behavior aligns with the standard - _`template-name`_ in the
_`simple-template-id`_ in the return type shall be the actual name of a
class template rather than some equivalent alias template. Details
https://github.com/llvm/llvm-project/issues/54909#issuecomment-2508418355.
2024-12-02 17:19:19 +02:00
Kazu Hirata
1e3e199ed9
[Sema] Migrate away from PointerUnion::{is,get} (NFC) (#117498)
Note that PointerUnion::{is,get} have been soft deprecated in
PointerUnion.h:

  // FIXME: Replace the uses of is(), get() and dyn_cast() with
  //        isa<T>, cast<T> and the llvm::dyn_cast<T>

I'm not touching PointerUnion::dyn_cast for now because it's a bit
complicated; we could blindly migrate it to dyn_cast_if_present, but
we should probably use dyn_cast when the operand is known to be
non-null.
2024-11-27 09:13:28 -08:00
Oleksandr T.
eb001820b4
[Clang] prevent errors for deduction guides using deduced type aliases (#117450)
Fixes #54909

--- 

Clang incorrectly produces diagnostics for alias templates in deduction
guides, treating them as separate from their underlying types. This
issue arises because Clang doesn't properly handle
`TypeAliasTemplateDecl` when comparing template names for equality in
the context of deduction guides, resulting in diagnostics that don't
align with the C++ standard. As the C++ standard specifies - _an alias
template is considered a synonym for its underlying type_

With this change, Clang now correctly resolves alias templates to their
underlying types in deduction guides, ensuring compliance with the C++
standard.
2024-11-27 11:51:34 +02:00
Kazu Hirata
46d750be2e
[Sema] Remove unused includes (NFC) (#116461)
Identified with misc-include-cleaner.
2024-11-16 07:37:33 -08:00
Joseph Huber
b9d678d22f
[Clang] Use TargetInfo when deciding if an address space is compatible (#115777)
Summary:
Address spaces are used in several embedded and GPU targets to describe
accesses to different types of memory. Currently we use the address
space enumerations to control which address spaces are considered
supersets of eachother, however this is also a target level property as
described by the C standard's passing mentions. This patch allows the
address space checks to use the target information to decide if a
pointer conversion is legal. For AMDGPU and NVPTX, all supported address
spaces can be converted to the default address space.

More semantic checks can be added on top of this, for now I'm mainly
looking to get more standard semantics working for C/C++. Right now the
address space conversions must all be done explicitly in C/C++ unlike
the offloading languages which define their own custom address spaces
that just map to the same target specific ones anyway. The main question
is if this behavior is a function of the target or the language.
2024-11-15 06:58:36 -06:00
Sirraide
dde802b153
[Clang] [NFC] Refactor AST visitors in Sema and the static analyser to use DynamicRecursiveASTVisitor (#115144)
This pr refactors all recursive AST visitors in `Sema`, `Analyze`, and
`StaticAnalysis` to inherit from DRAV instead. This is over half of the
visitors that inherit from RAV directly.

See also #115132, #110040, #93462

LLVM Compile-Time Tracker link for this branch:
https://llvm-compile-time-tracker.com/compare.php?from=5adb5c05a2e9f31385fbba8b0436cbc07d91a44d&to=b58e589a86c06ba28d4d90613864d10be29aa5ba&stat=instructions%3Au
2024-11-15 08:04:08 +01:00
Krystian Stasiowski
44ab3805b5
Revert "Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585, #111173)" (#111852)" (#115159)
This reverts commit 2bb3d3a3f32ffaef3d9b6a27db7f1941f0cb1136.
2024-11-06 09:25:29 -05: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
Boaz Brickner
8f25c0bc7d
[clang] Fix covariant cv-qualification check to require the override function return type to have the same or less cv-qualification (#112713)
This prevents changing cv-qualification from const to volatile or vice
versa, for example.

https://eel.is/c++draft/class.virtual#8.3

Previously, we checked that the new type is the same or more qualified
to return an error, but the standard requires the new type to be the
same or less qualified and since the cv-qualification is only partially
ordered, we cannot rely on a check on whether it is more qualified to
return an error. Now, we reversed the condition to check whether the old
is at least as qualified, and return an error if it is not.

Also, adjusted the error name and message to clarify the requirement and
added a missing closing parenthesis.

Added tests to cover different use cases for classes with different
qualifications and also refactored them to make them easier to follow:
1. Use override to make sure the function names actually match.
2. Named the function in a more descriptive way to clarify what each use
case is checking.

Fixes: #111742
2024-10-17 16:50:47 +02:00
Boaz Brickner
b333edd0d6
[clang] When checking for covariant return types, make sure the pointers or references are to *classes* (#111856)
https://eel.is/c++draft/class.virtual#8.1

This prevents overriding methods with non class return types that have
less cv-qualification.

Fixes: #111742
2024-10-16 16:02:25 +02:00
Krystian Stasiowski
2bb3d3a3f3
Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585, #111173)" (#111852)
This patch reapplies #111173, fixing a bug when instantiating dependent
expressions that name a member template that is later explicitly
specialized for a class specialization that is implicitly instantiated.

The bug is addressed by adding the `hasMemberSpecialization` function,
which return `true` if _any_ redeclaration is a member specialization.
This is then used when determining the instantiation pattern for a
specialization of a template, and when collecting template arguments for
a specialization of a template.
2024-10-11 14:08:06 -04:00
Krystian Stasiowski
1dff3309fd
Revert "Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585)" (#111173)" (#111766)
This reverts commit 4da8ac34f76e707ab94380b94f616457cfd2cb83.
2024-10-09 17:49:32 -04:00
Krystian Stasiowski
4da8ac34f7
Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585)" (#111173)
Reapplies #106585, fixing an issue where non-dependent names of member
templates appearing prior to that member template being explicitly
specialized for an implicitly instantiated class template specialization
would incorrectly use the definition of the explicitly specialized
member template.
2024-10-08 10:14:09 -04:00
Doug Wyatt
7fe43ada28
[Clang] nonblocking/nonallocating attributes: 2nd pass caller/callee analysis (#99656)
- In Sema, when encountering Decls with function effects needing
verification, add them to a vector, DeclsWithEffectsToVerify.
- Update AST serialization to include DeclsWithEffectsToVerify.
- In AnalysisBasedWarnings, use DeclsWithEffectsToVerify as a work
queue, verifying functions with declared effects, and inferring (when
permitted and necessary) whether their callees have effects.

---------

Co-authored-by: Doug Wyatt <dwyatt@apple.com>
Co-authored-by: Sirraide <aeternalmail@gmail.com>
Co-authored-by: Erich Keane <ekeane@nvidia.com>
2024-10-03 02:14:51 +02:00
Martin Storsjö
1818ca5c4a Revert "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585)"
This reverts commit cdd71d61664b63ae57bdba9ee0d891f78ef79c07 (and
30adb43c897a45c18d7dd163fb4ff40c915fc488).

This change broke compiling Qt, see
https://github.com/llvm/llvm-project/pull/106585#issuecomment-2365309463
for details.
2024-09-21 23:24:49 +03:00
Krystian Stasiowski
cdd71d6166
[Clang][Sema] Refactor collection of multi-level template argument lists (#106585)
Currently, clang rejects the following explicit specialization of `f`
due to the constraints not being equivalent:
```
template<typename T>
struct A
{
    template<bool B>
    void f() requires B;
};

template<>
template<bool B>
void A<int>::f() requires B { }
```
This happens because, in most cases, we do not set the flag indicating
whether a `RedeclarableTemplate` is an explicit specialization of a
member of an implicitly instantiated class template specialization until
_after_ we compare constraints for equivalence. This patch addresses the
issue (and a number of other issues) by:
- storing the flag indicating whether a declaration is a member
specialization on a per declaration basis, and
- significantly refactoring `Sema::getTemplateInstantiationArgs` so we
collect the right set of template argument in all cases.

Many of our declaration matching & constraint evaluation woes can be
traced back to bugs in `Sema::getTemplateInstantiationArgs`. This
change/refactor should fix a lot of them. It also paves the way for
fixing #101330 and #105462 per my suggestion in #102267 (which I have
implemented on top of this patch but will merge in a subsequent PR).
2024-09-20 14:57:40 -04:00
Chris B
03618ceabd
[HLSL] Fix move assignment of this (#108445)
Under HLSL 202x+ move assignment can occur and when targeting `this`
move assignment was generating some really odd errors. This corrects the
errors by properly generating the `this` object reference for HLSL and
always treating it as a reference.

This mirrors the implementation added eariler for copy assignment, and
extends the test case to cover both move and copy assignment under HLSL
202x+.
2024-09-13 17:36:41 -05:00
Matheus Izvekov
fa65804705
[clang] Implement CWG2398 provisional TTP matching to class templates (#94981)
This extends default argument deduction to cover class templates as
well, applying only to partial ordering, adding to the provisional
wording introduced in https://github.com/llvm/llvm-project/pull/89807.

This solves some ambuguity introduced in P0522 regarding how template
template parameters are partially ordered, and should reduce the
negative impact of enabling `-frelaxed-template-template-args` by
default.

Given the following example:
```C++
template <class T1, class T2 = float> struct A;
template <class T3> struct B;

template <template <class T4> class TT1, class T5> struct B<TT1<T5>>;   // #1
template <class T6, class T7>                      struct B<A<T6, T7>>; // #2

template struct B<A<int>>;
```
Prior to P0522, `#2` was picked. Afterwards, this became ambiguous. This
patch restores the pre-P0522 behavior, `#2` is picked again.
2024-09-07 15:49:07 -03:00
Mital Ashok
f1ac334b13
[Clang][SemaCXX] Preserve qualifiers in derived-to-base cast in defaulted comparison operators (#102619)
Fixes #102588

Co-authored-by: cor3ntin <corentinjabot@gmail.com>
2024-09-05 09:41:39 +02:00
Dan Liew
ff04c5b2e6
[NFC][Sema] Move Sema::AssignmentAction into its own scoped enum (#106453)
The primary motivation behind this is to allow the enum type to be
referred to earlier in the Sema.h file which is needed for #106321.

It was requested in #106321 that a scoped enum be used (rather than
moving the enum declaration earlier in the Sema class declaration).
Unfortunately doing this creates a lot of churn as all use sites of the
enum constants had to be changed. Appologies to all downstream forks in
advanced.

Note the AA_ prefix has been dropped from the enum value names as they
are now redundant.
2024-08-29 12:00:28 -07:00
Aaron Ballman
435cb0dc5e
[C++23] Fix infinite recursion (Clang 19.x regression) (#104829)
d469794d0cdfd2fea50a6ce0c0e33abb242d744c was fixing an issue with
triggering vtable instantiations, but it accidentally introduced
infinite recursion when the type to be checked is the same as the type
used in a base specifier or field declaration.

Fixes #104802
2024-08-19 16:54:12 -04:00
Sirraide
2b0a8fcf70
[Clang] Implement C++26’s P2893R3 ‘Variadic friends’ (#101448)
Implement P2893R3 ‘Variadic friends’ for C++26.

This closes #98587.

Co-authored-by: Younan Zhang <zyn7109@gmail.com>
2024-08-15 21:16:30 +02:00
Mital Ashok
c7df775440
[Clang] Check explicit object parameter for defaulted operators properly (#100419)
Previously, the type of explicit object parameters was not considered
for relational operators. This was defined by CWG2586,
<https://cplusplus.github.io/CWG/issues/2586.html>. This fix also means
CWG2547 <https://cplusplus.github.io/CWG/issues/2547.html> is now fully
implemented. Fixes #100329, fixes #104413.

Now start rejecting invalid rvalue reference parameters, which weren't
checked for, and start accepting non-reference explicit object
parameters (like `bool operator==(this C, C) = default;`) which were
previously rejected for the object param not being a reference.

Also start rejecting non-reference explicit object parameters for
defaulted copy/move assign operators (`A& operator=(this A, const A&) =
default;` is invalid but was previously accepted). Fixes #104414.
2024-08-15 19:12:11 +04:00
Mariya Podchishchaeva
d469794d0c
[clang] Avoid triggering vtable instantiation for C++23 constexpr dtor (#102605)
In C++23 anything can be constexpr, including a dtor of a class whose
members and bases don't have constexpr dtors. Avoid early triggering of
vtable instantiation int this case.

Fixes https://github.com/llvm/llvm-project/issues/102293
2024-08-12 09:08:46 +02:00
Chuanqi Xu
847f9cb0e8
Reland [C++20] [Modules] [Itanium ABI] Generate the vtable in the mod… (#102287)
Reland https://github.com/llvm/llvm-project/pull/75912

The differences of this PR between
https://github.com/llvm/llvm-project/pull/75912 are:

- Fixed a regression in `Decl::isInAnotherModuleUnit()` in DeclBase.cpp
pointed by @mizvekov and add the corresponding test.
- Fixed the regression in windows
https://github.com/llvm/llvm-project/issues/97447. The changes are in
`CodeGenModule::getVTableLinkage` from
`clang/lib/CodeGen/CGVTables.cpp`. According to the feedbacks from MSVC
devs, the linkage of vtables won't affected by modules. So I simply
skipped the case for MSVC.

Given this is more or less fundamental to the use of modules. I hope we
can backport this to 19.x.
2024-08-08 13:14:09 +08:00
Krystian Stasiowski
55ea36002b
[Clang][Sema] Make UnresolvedLookupExprs in class scope explicit specializations instantiation dependent (#100392)
A class member named by an expression in a member function that may instantiate to a static _or_ non-static member is represented by a `UnresolvedLookupExpr` in order to defer the implicit transformation to a class member access expression until instantiation. Since `ASTContext::getDecltypeType` only creates a `DecltypeType` that has a `DependentDecltypeType` as its canonical type when the operand is instantiation dependent, and since we do not transform types unless they are instantiation dependent, we need to mark the `UnresolvedLookupExpr` as instantiation dependent in order to correctly build a `DecltypeType` using the expression as its operand with a `DependentDecltypeType` canonical type. Fixes #99873.
2024-08-06 12:40:44 -04:00
smanna12
6e0a913973
[Clang][NFC] Remove unnecessary copy (#100688)
Reported by Static Analyzer Tool:

In Sema::checkIncorrectVTablePointerAuthenticationAttribute(): Using the
auto keyword without an & causes the copy of an object of type
CXXBaseSpecifier.
2024-07-26 07:27:09 -05:00
Mike Rice
51d4980a13
[clang][NFC] remove unneeded nullptr checks after dereference (#100489)
Fix static verifer concerns of null pointer checks after dereferencing  
the pointer. Update the assert to make it super clear it is not null and
remove the checks.
2024-07-25 08:03:16 -07:00
Doug Wyatt
0bb68b5571
Performance optimizations for function effects (nonblocking attribute etc.) (#96844)
- Put new FunctionProtoType trailing objects last.
- Inline FunctionEffectsRef::get()
- Manually inline FunctionEffectsRef::Profile().

---------

Co-authored-by: Doug Wyatt <dwyatt@apple.com>
2024-07-17 13:36:36 -04:00
MagentaTreehouse
bc8a8f5415
[clang][Sema] Improve Sema::CheckCXXDefaultArguments (#97338)
In the second loop in `Sema::CheckCXXDefaultArguments`, we don't need to
re-examine the first parameter with a default argument. Dropped the
first iteration of that loop.

In addition, use the preferred early `continue` for the if-statement in
the loop.
2024-07-17 14:09:35 +02:00
Sirraide
864478cc74
[Clang] Disallow explicit object parameters in more contexts (#89078)
This diagnoses explicit object parameters in more contexts
where they aren’t supposed to appear in (e.g. function pointer
types, non-function member decls, etc.) [dcl.fct]

This fixes #85992.
2024-07-16 01:55:11 +02:00
Haojian Wu
59e56eeb1d Revert "Reapply "[Clang] Implement resolution for CWG1835 (#92957)" (#98547)"
This reverts commit ce4aada6e2135e29839f672a6599db628b53295d and a
follow-up patch 8ef26f1289bf069ccc0d6383f2f4c0116a1206c1.

This new warning can not be fully suppressed by the
`-Wno-missing-dependent-template-keyword` flag, this gives developer no
time to do the cleanup in a large codebase, see https://github.com/llvm/llvm-project/pull/98547#issuecomment-2228250884
2024-07-15 13:22:40 +02:00
Oleksandr T
4ca024c877
[Clang] Fix cast failures by adjusting the resolution of record declaration contexts to handle semantic and lexical distinctions (#96228)
Fixes #96043
2024-07-15 10:00:19 +08:00
Krystian Stasiowski
ce4aada6e2
Reapply "[Clang] Implement resolution for CWG1835 (#92957)" (#98547)
Reapplies #92957, fixing an instance where the `template` keyword was
missing prior to a dependent name in `llvm/ADT/ArrayRef.h`. An
_alias-declaration_ is used to work around a bug affecting GCC releases
before 11.1 (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94799) which
rejects the use of the `template` keyword prior to the
_nested-name-specifier_ in the class member access.
2024-07-11 18:49:35 -04:00
NAKAMURA Takumi
d3923354a4 Revert "[Clang] Implement resolution for CWG1835 (#92957)"
ppc64le-lld-multistage-test has been failing.

This reverts commit 7bfb98c34687d9784f36937c3ff3e735698b498a.
2024-07-10 13:50:34 +09:00
Chuanqi Xu
91d40ef6e3 Revert "[C++20] [Modules] [Itanium ABI] Generate the vtable in the module unit of dynamic classes (#75912)"
This reverts commit 18f3bcbb13ca83d33223b00761d8cddf463e9ffb, 15bb02650e26875c48889053d6a9697444583721 and
99873b35da7ecb905143c8a6b8deca4d4416f1a9.

See the post commit message in
https://github.com/llvm/llvm-project/pull/75912 to see the reasons.
2024-07-10 10:58:18 +08:00
Krystian Stasiowski
7bfb98c346
[Clang] Implement resolution for CWG1835 (#92957)
CWG1835 was one of the many core issues resolved by P1787R6: "Declarations and where to
find them" (http://wg21.link/p1787r6). Its resolution changes how
member-qualified names (as defined by [basic.lookup.qual.general] p2) are looked
up. This patch implementation that resolution.

Previously, an _identifier_ following `.` or `->` would be first looked
up in the type of the object expression (i.e. qualified lookup), and
then in the context of the _postfix-expression_ (i.e. unqualified
lookup) if nothing was found; the result of the second lookup was
required to name a class template. Notably, this second lookup would
occur even when the object expression was dependent, and its result
would be used to determine whether a `<` token is the start of a
_template-argument_list_.

The new wording in [basic.lookup.qual.general] p2 states:
> A member-qualified name is the (unique) component name, if any, of
> - an _unqualified-id_ or
> - a _nested-name-specifier_ of the form _`type-name ::`_ or
_`namespace-name ::`​_
>
> in the id-expression of a class member access expression. A
***qualified name*** is
> - a member-qualified name or
> - the terminal name of
>     - a _qualified-id_,
>     - a _using-declarator_,
>     - a _typename-specifier_,
>     - a _qualified-namespace-specifier_, or
> - a _nested-name-specifier_, _elaborated-type-specifier_, or
_class-or-decltype_ that has a _nested-name-specifier_.
>
> The _lookup context_ of a member-qualified name is the type of its
associated object expression (considered dependent if the object
expression is type-dependent). The lookup context of any other qualified
name is the type, template, or namespace nominated by the preceding
_nested-name-specifier_.

And [basic.lookup.qual.general] p3 now states:
> _Qualified name lookup_ in a class, namespace, or enumeration performs
a search of the scope associated with it except as specified below.
Unless otherwise specified, a qualified name undergoes qualified name
lookup in its lookup context from the point where it appears unless the
lookup context either is dependent and is not the current instantiation
or is not a class or class template. If nothing is found by qualified
lookup for a member-qualified name that is the terminal name of a
_nested-name-specifier_ and is not dependent, it undergoes unqualified
lookup.

In non-standardese terms, these two paragraphs essentially state the
following:
- A name that immediately follows `.` or `->` in a class member access
expression is a member-qualified name
- A member-qualified name will be first looked up in the type of the
object expression `T` unless `T` is a dependent type that is _not_ the
current instantiation, e.g.
```
template<typename T>
struct A
{
    void f(T* t)
    {
        this->x; // type of the object expression is 'A<T>'. although 'A<T>' is dependent, it is the
                 // current instantiation so we look up 'x' in the template definition context.
        
        t->y; // type of the object expression is 'T' ('->' is transformed to '.' per [expr.ref]). 
              // 'T' is dependent and is *not* the current instantiation, so we lookup 'y' in the 
              // template instantiation context.
    }
};
```
- If the first lookup finds nothing and:
- the member-qualified name is the first component of a
_nested-name-specifier_ (which could be an _identifier_ or a
_simple-template-id_), and either:
- the type of the object expression is the current instantiation and it
has no dependent base classes, or
        - the type of the object expression is not dependent

  then we lookup the name again, this time via unqualified lookup.

Although the second (unqualified) lookup is stated not to occur when the
member-qualified name is dependent, a dependent name will _not_ be
dependent once the template is instantiated, so the second lookup must
"occur" during instantiation if qualified lookup does not find anything.
This means that we must perform the second (unqualified) lookup during
parsing even when the type of the object expression is dependent, but
those results are _not_ used to determine whether a `<` token is the
start of a _template-argument_list_; they are stored so we can replicate
the second lookup during instantiation.

In even simpler terms (paraphrasing the meeting minutes from the review of P1787; see https://wiki.edg.com/bin/view/Wg21summer2020/P1787%28Lookup%29Review2020-06-15Through2020-06-18):
- Unqualified lookup always happens for the first name in a
_nested-name-specifier_ that follows `.` or `->`
- The result of that lookup is only used to determine whether `<` is the
start of a _template-argument-list_ if the first (qualified) lookup
found nothing and the lookup context:
    - is not dependent, or 
    - is the current instantiation and has no dependent base classes.

An example:
```
struct A 
{
     void f();
};

template<typename T>
using B = A;

template<typename T>
struct C : A
{
    template<typename U>
    void g();

    void h(T* t)
    {
        this->g<int>(); // ok, '<' is the start of a template-argument-list ('g' was found via qualified lookup in the current instantiation)
        this->B<void>::f(); // ok, '<' is the start of a template-argument-list (current instantiation has no dependent bases, 'B' was found via unqualified lookup)
        t->g<int>(); // error: '<' means less than (unqualified lookup does not occur for a member-qualified name that isn't the first component of a nested-name-specifier)
        t->B<void>::f(); // error: '<' means less than (unqualified lookup does not occur if the name is dependent)
        t->template B<void>::f(); // ok: '<' is the start of a template-argument-list ('template' keyword used)
    }
};
```

Some additional notes:
- Per [basic.lookup.qual.general] p1, lookup for a
member-qualified name only considers namespaces, types, and templates
whose specializations are types if it's an _identifier_ followed by
`::`; lookup for the component name of a _simple-template-id_ followed
by `::` is _not_ subject to this rule.
- The wording which specifies when the second unqualified lookup occurs
appears to be paradoxical. We are supposed to do it only for the first
component name of a _nested-name-specifier_ that follows `.` or `->`
when qualified lookup finds nothing. However, when that name is followed
by `<` (potentially starting a _simple-template-id_) we don't _know_
whether it will be the start of a _nested-name-specifier_ until we do
the lookup -- but we aren't supposed to do the lookup until we know it's
part of a _nested-name-specifier_! ***However***, since we only do the
second lookup when the first lookup finds nothing (and the name isn't
dependent), ***and*** since neither lookup is type-only, the only valid
option is for the name to be the _template-name_ in a
_simple-template-id_ that is followed by `::` (it can't be an
_unqualified-id_ naming a member because we already determined that the
lookup context doesn't have a member with that name). Thus, we can lock
into the _nested-name-specifier_ interpretation and do the second lookup
without having to know whether the _simple-template-id_ will be followed
by `::` yet.
2024-07-09 19:00:19 -04:00
Vlad Serebrennikov
bae2c54912 [clang][NFC] Move documentation of Sema functions into Sema.h
This patch moves documentation of `Sema` functions from `.cpp` files to `Sema.h` when there was no documentation in the latter, or it can be trivially subsumed. More complicated cases when there's less trivial divergence between documentation attached to declaration and the one attached to implementation are left for a later PR that would require review.

It appears that doxygen can find the documentation for a function defined out-of-line even if it's attached to an implementation, and not declaration. But other tools, e.g. clangd, are not as powerful. So this patch significantly improves autocompletion experience for (at least) clangd-based IDEs.
2024-07-01 20:55:57 +03: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
Doug Wyatt
f03cb005eb
[Clang] Introduce nonblocking/nonallocating attributes (#84983)
Introduce `nonblocking` and `nonallocating` attributes. RFC is here:
https://discourse.llvm.org/t/rfc-nolock-and-noalloc-attributes/76837

This PR introduces the attributes, with some changes in Sema to deal
with them as extensions to function (proto)types.

There are some basic type checks, most importantly, a warning when
trying to spoof the attribute (implicitly convert a function without the
attribute to one that has it).

A second, follow-on pull request will introduce new caller/callee
verification.
---------
Co-authored-by: Doug Wyatt <dwyatt@apple.com>
Co-authored-by: Shafik Yaghmour <shafik.yaghmour@intel.com>
Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
Co-authored-by: Sirraide <aeternalmail@gmail.com>
2024-06-24 12:51:31 +02:00
Vlad Serebrennikov
bc4d50f02d
[clang] Implement CWG2877 "Type-only lookup for using-enum-declarator" (#95399)
This patch implements 2024-05-31 resolution of a tentatively ready issue
[CWG2877](https://cplusplus.github.io/CWG/issues/2877.html) "Type-only
lookup for using-enum-declarator", which supersedes earlier
[CWG2621](https://cplusplus.github.io/CWG/issues/2621.html) "Kind of
lookup for `using enum` declarations".

Now we perform type-only lookup (not to be confused with type-only
context) for `elaborated-enum-declarator`. This is the same kind of
lookup that elaborated type specifiers and base specifiers undergo.

I also found out (and fixed) that one of our existing tests claimed that
a dependent type can be used in `elaborated-enum-declarator`, but that's
not the case:
> The
[using-enum-declarator](http://eel.is/c++draft/enum.udecl#nt:using-enum-declarator)
shall designate a non-dependent type with a reachable
[enum-specifier](http://eel.is/c++draft/dcl.enum#nt:enum-specifier)[.](http://eel.is/c++draft/enum.udecl#1.sentence-2)
2024-06-21 13:49:43 +04:00
David Green
b635d690ed [NFC] Fix laod -> load typos. NFC 2024-06-21 09:26:44 +01:00
Krystian Stasiowski
9a88aa0e2b
[Clang][Sema] Diagnose variable template explicit specializations with storage-class-specifiers (#93873)
According to [temp.expl.spec] p2:
> The declaration in an _explicit-specialization_ shall not be an
_export-declaration_. An explicit specialization shall not use a
_storage-class-specifier_ other than `thread_local`.

Clang partially implements this, but a number of issues exist:
1. We don't diagnose class scope explicit specializations of variable
templates with _storage-class-specifiers_, e.g.
    ```
    struct A
    {
        template<typename T>
        static constexpr int x = 0;

        template<>
static constexpr int x<void> = 1; // ill-formed, but clang accepts
    };
    ````
2. We incorrectly reject class scope explicit specializations of
variable templates when `static` is not used, e.g.
    ```
    struct A
    {
        template<typename T>
        static constexpr int x = 0;

        template<>
constexpr int x<void> = 1; // error: non-static data member cannot be
constexpr; did you intend to make it static?
    };
    ````
3. We don't diagnose dependent class scope explicit specializations of
function templates with storage class specifiers, e.g.
    ```
    template<typename T>
    struct A
    {
        template<typename U>
        static void f();

        template<>
        static void f<int>(); // ill-formed, but clang accepts
    };
    ````

This patch addresses these issues as follows:
- # 1 is fixed by issuing a diagnostic when an explicit
specialization of a variable template has storage class specifier
- # 2 is fixed by considering any non-function declaration with any
template parameter lists at class scope to be a static data member. This
also allows for better error recovery (it's more likely the user
intended to declare a variable template than a "field template").
- # 3 is fixed by checking whether a function template explicit
specialization has a storage class specifier even when the primary
template is not yet known.

One thing to note is that it would be far simpler to diagnose this when
parsing the _decl-specifier-seq_, but such an implementation would
necessitate a refactor of `ParsedTemplateInfo` which I believe to be
outside the scope of this patch.
2024-06-18 13:40:31 -04:00
Chuanqi Xu
15bb02650e
[C++20] [Modules] [Itanium ABI] Generate the vtable in the module unit of dynamic classes (#75912)
Close https://github.com/llvm/llvm-project/issues/70585 and reflect
https://github.com/itanium-cxx-abi/cxx-abi/issues/170.

The significant change of the patch is: for dynamic classes attached to
module units, we generate the vtable to the attached module units
directly and the key functions for such classes is meaningless.
2024-06-17 10:25:35 +08:00