[clang] [Clang] Only non-overloaded dereference expressions are lvalues (PR #93457)

2024-05-27 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/93457
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [Clang] Unify interface for accessing template arguments as written for class/variable template specializations (PR #81642)

2024-05-27 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@kimgr The linked code seems to only be concerned with the `SourceLocation` of 
the `Decl` (which should be the same `SourceLocation` returned by 
`Decl::getLocation`), and the template arguments as written (which can be 
accessed via `getTemplateArgsAsWritten` per this patch). I would imagine the 
fix here would be to handle explicit instantiations of class templates the same 
what you handle explicit instantiations of function templates (which also do 
not store a `TypeLoc` but can have their template arguments as written accessed 
in a similar manner).

https://github.com/llvm/llvm-project/pull/81642
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Implement resolution for CWG1835 (PR #92957)

2024-05-22 Thread Krystian Stasiowski via cfe-commits


@@ -55,15 +55,21 @@ namespace PR11856 {
 
   template T *end(T*);
 
-  class X { };
+  struct X { };
+  struct Y {
+int end;
+  };
   template 
   void Foo2() {
 T it1;
-if (it1->end < it1->end) {
-}
+if (it1->end < it1->end) { }
 
 X *x;
-if (x->end < 7) {  // expected-error{{no member named 'end' in 
'PR11856::X'}}
-}
+if (x->end < 7) { } // expected-error{{expected '>'}}
+// expected-note@-1{{to match this '<'}}
+// expected-error@-2{{expected unqualified-id}}

sdkrystian wrote:

This actually is expected -- see the final note in the comments of the PR. 
Since we didn't find anything via qualified lookup, we "lock into" the 
nested-name-specifier interpretation (because it would otherwise be an invalid 
class member access since such a member doesn't exist). So, we do unqualified 
lookup, find the template, and try parse `<` as a template argument list. 

https://github.com/llvm/llvm-project/pull/92957
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Distinguish unresolved templates in UnresolvedLookupExpr (PR #89019)

2024-05-22 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@zyn0217 Yes, both examples are of uninstantiable templates & are intended to 
be diagnosed by #90152.

https://github.com/llvm/llvm-project/pull/89019
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Implement resolution for CWG1835 (PR #92957)

2024-05-21 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@Endilll I'm still in the process of writing tests, but I'll add several soon. 
I'm quite confident about my interpretation being correct but I just want to be 
100% sure :). 

At the very least this patch gets [[basic.lookup.qual.general] example 
3](http://eel.is/c++draft/basic.lookup.qual.general#example-3) right, in 
addition to the examples I provided in the PR.

https://github.com/llvm/llvm-project/pull/92957
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Implement resolution for CWG1835 (PR #92957)

2024-05-21 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92957

>From 4524db5ae7f3133b51328fbabd1f6188d7d3707b Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Tue, 21 May 2024 13:15:24 -0400
Subject: [PATCH 1/2] [WIP][Clang] Implement resolution for CWG1835

---
 clang/include/clang/Sema/DeclSpec.h   |  8 +++
 clang/include/clang/Sema/Sema.h   |  2 +-
 clang/lib/Parse/ParseDeclCXX.cpp  |  2 +-
 clang/lib/Parse/ParseExpr.cpp |  9 +--
 clang/lib/Sema/SemaCXXScopeSpec.cpp   | 60 +--
 clang/lib/Sema/SemaExprMember.cpp | 10 +---
 clang/lib/Sema/SemaPseudoObject.cpp   | 16 ++---
 clang/lib/Sema/SemaTemplate.cpp   | 22 ---
 clang/lib/Sema/TreeTransform.h| 15 +
 .../basic.lookup.classref/p1-cxx11.cpp| 16 +++--
 .../basic.lookup/basic.lookup.classref/p1.cpp | 16 +++--
 .../class.derived/class.member.lookup/p8.cpp  |  4 +-
 clang/test/CXX/drs/cwg1xx.cpp |  9 +--
 clang/test/SemaCXX/static-assert-cxx17.cpp|  2 +-
 .../SemaTemplate/temp_arg_nontype_cxx20.cpp   |  2 +-
 15 files changed, 128 insertions(+), 65 deletions(-)

diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..c6d87ca1683a8 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -75,6 +75,7 @@ class CXXScopeSpec {
   SourceRange Range;
   NestedNameSpecifierLocBuilder Builder;
   ArrayRef TemplateParamLists;
+  NamedDecl *FoundFirstQualifierInScope;
 
 public:
   SourceRange getRange() const { return Range; }
@@ -91,6 +92,13 @@ class CXXScopeSpec {
 return TemplateParamLists;
   }
 
+  void setFoundFirstQualifierInScope(NamedDecl *Found) {
+FoundFirstQualifierInScope = Found;
+  }
+  NamedDecl *getFirstQualifierFoundInScope() const {
+return FoundFirstQualifierInScope;
+  }
+
   /// Retrieve the representation of the nested-name-specifier.
   NestedNameSpecifier *getScopeRep() const {
 return Builder.getRepresentation();
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 5894239664c15..805d36fd10544 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6891,7 +6891,7 @@ class Sema final : public SemaBase {
   const TemplateArgumentListInfo *TemplateArgs);
 
   ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
-   tok::TokenKind OpKind, CXXScopeSpec ,
+   bool IsArrow, CXXScopeSpec ,
SourceLocation TemplateKWLoc,
UnqualifiedId , Decl *ObjCImpDecl);
 
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 5eaec2b621e6f..b2fa6da002f98 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -720,7 +720,7 @@ Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
   return nullptr;
 }
 CXXScopeSpec SS;
-if (ParseOptionalCXXScopeSpecifier(SS, /*ParsedType=*/nullptr,
+if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
/*ObectHasErrors=*/false,
/*EnteringConttext=*/false,
/*MayBePseudoDestructor=*/nullptr,
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index eb7447fa038e4..b3c25f88b403d 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2254,6 +2254,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
   }
   break;
 }
+
 ParseOptionalCXXScopeSpecifier(
 SS, ObjectType, LHS.get() && LHS.get()->containsErrors(),
 /*EnteringContext=*/false, );
@@ -2328,10 +2329,10 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
   }
 
   if (!LHS.isInvalid())
-LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc,
-OpKind, SS, TemplateKWLoc, Name,
- CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
-   : nullptr);
+LHS = Actions.ActOnMemberAccessExpr(
+getCurScope(), LHS.get(), OpLoc, OpKind == tok::arrow, SS,
+TemplateKWLoc, Name,
+CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : nullptr);
   if (!LHS.isInvalid()) {
 if (Tok.is(tok::less))
   checkPotentialAngleBracket(LHS);
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index c405fbc0aa421..6efa8925d1446 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -397,11 +397,19 @@ NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, 
NestedNameSpecifier *NNS) {
   while 

[clang] [Clang] Implement resolution for CWG1835 (PR #92957)

2024-05-21 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

(this PR is by no means complete, but I would like feedback regarding the 
validity of my interpretation of the DR resolution and perhaps some guidance 
with how to best go about implementing it. The currently included 
implementation _works_, but I'm uncertain whether it's the best way of going 
about it).

https://github.com/llvm/llvm-project/pull/92957
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Implement resolution for CWG1835 (PR #92957)

2024-05-21 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/92957

[CWG1835](https://cplusplus.github.io/CWG/issues/1835.html) 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](http://eel.is/c++draft/basic.lookup.qual.general#2) are looked up. This 
patch is a draft implementation of 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](eel.is/c++draft/basic.lookup.qual.general#2) 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](eel.is/c++draft/basic.lookup.qual.general#3) 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.
```cpp
template
struct A
{
void f(T* t)
{
this->x; // type of the object expression is 'A'. although 'A' 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](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 

[clang] [Clang][Sema] Do not add implicit 'const' when matching constexpr function template explicit specializations after C++14 (PR #92449)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/92449
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Do not add implicit 'const' when matching constexpr function template explicit specializations after C++14 (PR #92449)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92449

>From f1a55b4f341990df2dc6edd740801486ca43488a Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 15:47:04 -0400
Subject: [PATCH 1/2] [Clang][Sema] Do not add implicit 'const' when matching
 constexpr function template explicit specializations after C++14

---
 clang/lib/Sema/SemaTemplate.cpp   | 15 ++--
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 13 +++-
 .../CXX/temp/temp.spec/temp.expl.spec/p12.cpp | 70 +++
 3 files changed, 90 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index de884260790cc..02d9b64c2b14b 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -10255,15 +10255,20 @@ bool Sema::CheckFunctionTemplateSpecialization(
 Ovl->getDeclContext()->getRedeclContext()))
 continue;
 
+  QualType FT = FD->getType();
+  // C++11 [dcl.constexpr]p8:
+  //   A constexpr specifier for a non-static member function that is not
+  //   a constructor declares that member function to be const.
+  //
   // When matching a constexpr member function template specialization
   // against the primary template, we don't yet know whether the
   // specialization has an implicit 'const' (because we don't know whether
   // it will be a static member function until we know which template it
-  // specializes), so adjust it now assuming it specializes this template.
-  QualType FT = FD->getType();
-  if (FD->isConstexpr()) {
-CXXMethodDecl *OldMD =
-  dyn_cast(FunTmpl->getTemplatedDecl());
+  // specializes). This rule was removed in C++14.
+  if (auto *NewMD = dyn_cast(FD);
+  !getLangOpts().CPlusPlus14 && NewMD && NewMD->isConstexpr() &&
+  !isa(NewMD)) {
+auto *OldMD = dyn_cast(FunTmpl->getTemplatedDecl());
 if (OldMD && OldMD->isConst()) {
   const FunctionProtoType *FPT = FT->castAs();
   FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index 788e93b56bb38..9e890204c78bd 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -89,6 +89,9 @@ struct S {
   template constexpr T f(); // expected-warning 0-1{{C++14}} 
expected-note 0-1{{candidate}}
   template 
   T g() const; // expected-note-re {{candidate template ignored: could not 
match 'T (){{( __attribute__\(\(thiscall\)\))?}} const' against 'char (){{( 
__attribute__\(\(thiscall\)\))?}}'}}
+#if __cplusplus >= 201402L
+  // expected-note@-2 {{candidate template ignored: could not match 'T () 
const' against 'int ()'}}
+#endif
 };
 
 // explicit specialization can differ in constepxr
@@ -100,13 +103,17 @@ template <> notlit S::f() const { return notlit(); }
 #if __cplusplus >= 201402L
 // expected-error@-2 {{no function template matches}}
 #endif
-template <> constexpr int S::g() { return 0; } // expected-note {{previous}}
+template <> constexpr int S::g() { return 0; }
 #if __cplusplus < 201402L
 // expected-warning@-2 {{C++14}}
+// expected-note@-3 {{previous}}
 #else
-// expected-error@-4 {{does not match any declaration in 'S'}}
+// expected-error@-5 {{no function template matches function template 
specialization 'g'}}
+#endif
+template <> int S::g() const;
+#if __cplusplus < 201402L
+// expected-error@-2 {{non-constexpr declaration of 'g' follows constexpr 
declaration}}
 #endif
-template <> int S::g() const; // expected-error {{non-constexpr declaration of 
'g' follows constexpr declaration}}
 // specializations can drop the 'constexpr' but not the implied 'const'.
 template <> char S::g() { return 0; } // expected-error {{no function template 
matches}}
 template <> double S::g() const { return 0; } // ok
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp 
b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
new file mode 100644
index 0..2a57489083695
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify=expected,cxx11 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify=expected,since-cxx14 %s
+
+struct A {
+  template
+  void f0();
+
+  template<>
+  constexpr void f0(); // cxx11-error {{conflicting types for 'f0'}}
+  // cxx11-note@-1 {{previous declaration is here}}
+  // cxx11-warning@-2 {{'constexpr' non-static 
member function will not be implicitly 'const' in C++14; add 'const'}}
+
+  template
+  void f1() const; // since-cxx14-note 2{{candidate template ignored: could 
not match 'void () const' against 

[clang] [clang-tools-extra] [Clang][Sema] Diagnose current instantiation used as an incomplete base class (PR #92597)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/92597
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Properly set the value category of dependent unary operators (PR #88740)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

Ping @cor3ntin ^

https://github.com/llvm/llvm-project/pull/88740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [Clang][Sema] Diagnose current instantiation used as an incomplete base class (PR #92597)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92597

>From 697004547e8855787e7dd248508c9453b9df7e4d Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Fri, 17 May 2024 13:30:04 -0400
Subject: [PATCH 1/8] [Clang][Sema] Diagnose current instantiation used a
 incomplete base class

---
 clang/lib/AST/Type.cpp|   4 +
 clang/lib/Sema/SemaDeclCXX.cpp| 116 +-
 .../basic.lookup.qual/class.qual/p2.cpp   |  10 +-
 clang/test/SemaTemplate/dependent-names.cpp   |   9 +-
 .../test/SemaTemplate/destructor-template.cpp |  14 ++-
 .../test/SemaTemplate/typo-dependent-name.cpp |   7 +-
 6 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e31741cd44240..4ad764b67f81f 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2372,6 +2372,10 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
   *Def = Rec;
 return !Rec->isCompleteDefinition();
   }
+  case InjectedClassName: {
+CXXRecordDecl *Rec = cast(CanonicalType)->getDecl();
+return Rec->isBeingDefined();
+  }
   case ConstantArray:
   case VariableArray:
 // An array is incomplete if its element type is incomplete
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8225381985052..84033a602f131 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2704,28 +2704,53 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 Access = AS_public;
 
   QualType BaseType = TInfo->getType();
+  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
   if (BaseType->containsErrors()) {
 // Already emitted a diagnostic when parsing the error type.
 return nullptr;
   }
-  // C++ [class.union]p1:
-  //   A union shall not have base classes.
-  if (Class->isUnion()) {
-Diag(Class->getLocation(), diag::err_base_clause_on_union)
-  << SpecifierRange;
-return nullptr;
-  }
 
-  if (EllipsisLoc.isValid() &&
-  !TInfo->getType()->containsUnexpandedParameterPack()) {
+  if (EllipsisLoc.isValid() && !BaseType->containsUnexpandedParameterPack()) {
 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
   << TInfo->getTypeLoc().getSourceRange();
 EllipsisLoc = SourceLocation();
   }
 
-  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
+  auto *BaseDecl =
+  dyn_cast_if_present(computeDeclContext(BaseType));
+  // C++ [class.derived.general]p2:
+  //   A class-or-decltype shall denote a (possibly cv-qualified) class type
+  //   that is not an incompletely defined class; any cv-qualifiers are
+  //   ignored.
+  if (BaseDecl) {
+// C++ [class.union.general]p4:
+// [...]  A union shall not be used as a base class.
+if (BaseDecl->isUnion()) {
+  Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
+  return nullptr;
+}
+
+// For the MS ABI, propagate DLL attributes to base class templates.
+if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+Context.getTargetInfo().getTriple().isPS()) {
+  if (Attr *ClassAttr = getDLLAttr(Class)) {
+if (auto *BaseSpec =
+dyn_cast(BaseDecl)) {
+  propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseSpec,
+  BaseLoc);
+}
+  }
+}
 
-  if (BaseType->isDependentType()) {
+if (RequireCompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class,
+SpecifierRange)) {
+  Class->setInvalidDecl();
+  return nullptr;
+}
+  } else if (!BaseType->isDependentType()) {
+Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
+return nullptr;
+  } else {
 // Make sure that we don't have circular inheritance among our dependent
 // bases. For non-dependent bases, the check for completeness below handles
 // this.
@@ -2750,65 +2775,28 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 // constexpr evaluator). If this case happens (in errory-recovery mode), we
 // explicitly mark the Class decl invalid. The diagnostic was already
 // emitted.
-if (!Class->getTypeForDecl()->isDependentType())
+if (!Class->isDependentContext())
   Class->setInvalidDecl();
 return new (Context) CXXBaseSpecifier(
 SpecifierRange, Virtual, Class->getTagKind() == TagTypeKind::Class,
 Access, TInfo, EllipsisLoc);
   }
 
-  // Base specifiers must be record types.
-  if (!BaseType->isRecordType()) {
-Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // C++ [class.union]p1:
-  //   A union shall not be used as a base class.
-  if (BaseType->isUnionType()) {
-Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // For the MS ABI, propagate DLL attributes to base class templates.
-  if 

[clang] [Clang][Sema] Don't build CXXDependentScopeMemberExprs for potentially implicit class member access expressions (PR #92318)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/92318
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Don't build CXXDependentScopeMemberExprs for potentially implicit class member access expressions (PR #92318)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92318

>From 72f0013122b764c7295a9b80b1f886b2eb38fb1d Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 15 May 2024 16:13:03 -0400
Subject: [PATCH 1/5] [Clang][Sema] Don't build CXXDependentScopeMemberExprs
 for potentially implicit class member access expressions

---
 clang/include/clang/Sema/Sema.h   | 11 +--
 clang/lib/Sema/SemaCXXScopeSpec.cpp   |  8 ++
 clang/lib/Sema/SemaExpr.cpp   | 31 ++
 clang/lib/Sema/SemaTemplate.cpp   | 98 ++-
 clang/lib/Sema/TreeTransform.h|  6 +-
 .../class.mfct/class.mfct.non-static/p3.cpp   | 91 -
 ...ms-function-specialization-class-scope.cpp | 52 ++
 .../ms-lookup-template-base-classes.cpp   | 12 +--
 .../ASTMatchers/ASTMatchersNodeTest.cpp   |  6 +-
 9 files changed, 206 insertions(+), 109 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6c89d275215de..5894239664c15 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5375,11 +5375,9 @@ class Sema final : public SemaBase {
   bool UseArgumentDependentLookup(const CXXScopeSpec , const LookupResult 
,
   bool HasTrailingLParen);
 
-  ExprResult
-  BuildQualifiedDeclarationNameExpr(CXXScopeSpec ,
-const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S,
-TypeSourceInfo **RecoveryTSI = nullptr);
+  ExprResult BuildQualifiedDeclarationNameExpr(
+  CXXScopeSpec , const DeclarationNameInfo ,
+  bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
 
   ExprResult BuildDeclarationNameExpr(const CXXScopeSpec , LookupResult ,
   bool NeedsADL,
@@ -8991,7 +8989,8 @@ class Sema final : public SemaBase {
   ExprResult
   BuildQualifiedTemplateIdExpr(CXXScopeSpec , SourceLocation TemplateKWLoc,
const DeclarationNameInfo ,
-   const TemplateArgumentListInfo *TemplateArgs);
+   const TemplateArgumentListInfo *TemplateArgs,
+   bool IsAddressOfOperand);
 
   TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec ,
  SourceLocation TemplateKWLoc,
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index fca5bd131bbc0..c405fbc0aa421 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -796,6 +796,14 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, 
NestedNameSpecInfo ,
 Diag(IdInfo.IdentifierLoc,
  diag::ext_undeclared_unqual_id_with_dependent_base)
 << IdInfo.Identifier << ContainingClass;
+// Fake up a nested-name-specifier that starts with the
+// injected-class-name of the enclosing class.
+QualType T = Context.getTypeDeclType(ContainingClass);
+TypeLocBuilder TLB;
+TLB.pushTrivial(Context, T, IdInfo.IdentifierLoc);
+SS.Extend(Context, /*TemplateKWLoc=*/SourceLocation(),
+  TLB.getTypeLocInContext(Context, T), IdInfo.IdentifierLoc);
+// Add the identifier to form a dependent name.
 SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc,
   IdInfo.CCLoc);
 return false;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f2d0a93d9a1e7..b2077df062d49 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2946,26 +2946,14 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec ,
 /// this path.
 ExprResult Sema::BuildQualifiedDeclarationNameExpr(
 CXXScopeSpec , const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S, TypeSourceInfo **RecoveryTSI) {
-  if (NameInfo.getName().isDependentName())
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  DeclContext *DC = computeDeclContext(SS, false);
-  if (!DC)
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  if (RequireCompleteDeclContext(SS, DC))
-return ExprError();
-
+bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI) {
   LookupResult R(*this, NameInfo, LookupOrdinaryName);
-  LookupQualifiedName(R, DC);
+  LookupParsedName(R, /*S=*/nullptr, , /*ObjectType=*/QualType());
 
   if (R.isAmbiguous())
 return ExprError();
 
-  if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)
+  if (R.wasNotFoundInCurrentInstantiation() || SS.isInvalid())
 return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
   

[clang] [Clang][Sema] Do not add implicit 'const' when matching constexpr function template explicit specializations after C++14 (PR #92449)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92449

>From 0e73c984a4215207b2842f60ac4dcaeb63230407 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 15:47:04 -0400
Subject: [PATCH 1/2] [Clang][Sema] Do not add implicit 'const' when matching
 constexpr function template explicit specializations after C++14

---
 clang/lib/Sema/SemaTemplate.cpp   | 15 ++--
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 13 +++-
 .../CXX/temp/temp.spec/temp.expl.spec/p12.cpp | 70 +++
 3 files changed, 90 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8a7af678b33d3..051814643ed88 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -10290,15 +10290,20 @@ bool Sema::CheckFunctionTemplateSpecialization(
 Ovl->getDeclContext()->getRedeclContext()))
 continue;
 
+  QualType FT = FD->getType();
+  // C++11 [dcl.constexpr]p8:
+  //   A constexpr specifier for a non-static member function that is not
+  //   a constructor declares that member function to be const.
+  //
   // When matching a constexpr member function template specialization
   // against the primary template, we don't yet know whether the
   // specialization has an implicit 'const' (because we don't know whether
   // it will be a static member function until we know which template it
-  // specializes), so adjust it now assuming it specializes this template.
-  QualType FT = FD->getType();
-  if (FD->isConstexpr()) {
-CXXMethodDecl *OldMD =
-  dyn_cast(FunTmpl->getTemplatedDecl());
+  // specializes). This rule was removed in C++14.
+  if (auto *NewMD = dyn_cast(FD);
+  !getLangOpts().CPlusPlus14 && NewMD && NewMD->isConstexpr() &&
+  !isa(NewMD)) {
+auto *OldMD = dyn_cast(FunTmpl->getTemplatedDecl());
 if (OldMD && OldMD->isConst()) {
   const FunctionProtoType *FPT = FT->castAs();
   FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index 788e93b56bb38..9e890204c78bd 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -89,6 +89,9 @@ struct S {
   template constexpr T f(); // expected-warning 0-1{{C++14}} 
expected-note 0-1{{candidate}}
   template 
   T g() const; // expected-note-re {{candidate template ignored: could not 
match 'T (){{( __attribute__\(\(thiscall\)\))?}} const' against 'char (){{( 
__attribute__\(\(thiscall\)\))?}}'}}
+#if __cplusplus >= 201402L
+  // expected-note@-2 {{candidate template ignored: could not match 'T () 
const' against 'int ()'}}
+#endif
 };
 
 // explicit specialization can differ in constepxr
@@ -100,13 +103,17 @@ template <> notlit S::f() const { return notlit(); }
 #if __cplusplus >= 201402L
 // expected-error@-2 {{no function template matches}}
 #endif
-template <> constexpr int S::g() { return 0; } // expected-note {{previous}}
+template <> constexpr int S::g() { return 0; }
 #if __cplusplus < 201402L
 // expected-warning@-2 {{C++14}}
+// expected-note@-3 {{previous}}
 #else
-// expected-error@-4 {{does not match any declaration in 'S'}}
+// expected-error@-5 {{no function template matches function template 
specialization 'g'}}
+#endif
+template <> int S::g() const;
+#if __cplusplus < 201402L
+// expected-error@-2 {{non-constexpr declaration of 'g' follows constexpr 
declaration}}
 #endif
-template <> int S::g() const; // expected-error {{non-constexpr declaration of 
'g' follows constexpr declaration}}
 // specializations can drop the 'constexpr' but not the implied 'const'.
 template <> char S::g() { return 0; } // expected-error {{no function template 
matches}}
 template <> double S::g() const { return 0; } // ok
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp 
b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
new file mode 100644
index 0..2a57489083695
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify=expected,cxx11 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify=expected,since-cxx14 %s
+
+struct A {
+  template
+  void f0();
+
+  template<>
+  constexpr void f0(); // cxx11-error {{conflicting types for 'f0'}}
+  // cxx11-note@-1 {{previous declaration is here}}
+  // cxx11-warning@-2 {{'constexpr' non-static 
member function will not be implicitly 'const' in C++14; add 'const'}}
+
+  template
+  void f1() const; // since-cxx14-note 2{{candidate template ignored: could 
not match 'void () const' against 

[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/92452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Don't build CXXDependentScopeMemberExprs for potentially implicit class member access expressions (PR #92318)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92318

>From 298b2fec54595e5c3c99070cbe856a36e1b71c95 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 15 May 2024 16:13:03 -0400
Subject: [PATCH 1/5] [Clang][Sema] Don't build CXXDependentScopeMemberExprs
 for potentially implicit class member access expressions

---
 clang/include/clang/Sema/Sema.h   | 11 +--
 clang/lib/Sema/SemaCXXScopeSpec.cpp   |  8 ++
 clang/lib/Sema/SemaExpr.cpp   | 31 ++
 clang/lib/Sema/SemaTemplate.cpp   | 98 ++-
 clang/lib/Sema/TreeTransform.h|  6 +-
 .../class.mfct/class.mfct.non-static/p3.cpp   | 91 -
 ...ms-function-specialization-class-scope.cpp | 52 ++
 .../ms-lookup-template-base-classes.cpp   | 12 +--
 .../ASTMatchers/ASTMatchersNodeTest.cpp   |  6 +-
 9 files changed, 206 insertions(+), 109 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6c89d275215de..5894239664c15 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5375,11 +5375,9 @@ class Sema final : public SemaBase {
   bool UseArgumentDependentLookup(const CXXScopeSpec , const LookupResult 
,
   bool HasTrailingLParen);
 
-  ExprResult
-  BuildQualifiedDeclarationNameExpr(CXXScopeSpec ,
-const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S,
-TypeSourceInfo **RecoveryTSI = nullptr);
+  ExprResult BuildQualifiedDeclarationNameExpr(
+  CXXScopeSpec , const DeclarationNameInfo ,
+  bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
 
   ExprResult BuildDeclarationNameExpr(const CXXScopeSpec , LookupResult ,
   bool NeedsADL,
@@ -8991,7 +8989,8 @@ class Sema final : public SemaBase {
   ExprResult
   BuildQualifiedTemplateIdExpr(CXXScopeSpec , SourceLocation TemplateKWLoc,
const DeclarationNameInfo ,
-   const TemplateArgumentListInfo *TemplateArgs);
+   const TemplateArgumentListInfo *TemplateArgs,
+   bool IsAddressOfOperand);
 
   TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec ,
  SourceLocation TemplateKWLoc,
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index fca5bd131bbc0..c405fbc0aa421 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -796,6 +796,14 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, 
NestedNameSpecInfo ,
 Diag(IdInfo.IdentifierLoc,
  diag::ext_undeclared_unqual_id_with_dependent_base)
 << IdInfo.Identifier << ContainingClass;
+// Fake up a nested-name-specifier that starts with the
+// injected-class-name of the enclosing class.
+QualType T = Context.getTypeDeclType(ContainingClass);
+TypeLocBuilder TLB;
+TLB.pushTrivial(Context, T, IdInfo.IdentifierLoc);
+SS.Extend(Context, /*TemplateKWLoc=*/SourceLocation(),
+  TLB.getTypeLocInContext(Context, T), IdInfo.IdentifierLoc);
+// Add the identifier to form a dependent name.
 SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc,
   IdInfo.CCLoc);
 return false;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5ecfdee21f09d..ebf02ae566044 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2946,26 +2946,14 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec ,
 /// this path.
 ExprResult Sema::BuildQualifiedDeclarationNameExpr(
 CXXScopeSpec , const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S, TypeSourceInfo **RecoveryTSI) {
-  if (NameInfo.getName().isDependentName())
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  DeclContext *DC = computeDeclContext(SS, false);
-  if (!DC)
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  if (RequireCompleteDeclContext(SS, DC))
-return ExprError();
-
+bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI) {
   LookupResult R(*this, NameInfo, LookupOrdinaryName);
-  LookupQualifiedName(R, DC);
+  LookupParsedName(R, /*S=*/nullptr, , /*ObjectType=*/QualType());
 
   if (R.isAmbiguous())
 return ExprError();
 
-  if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)
+  if (R.wasNotFoundInCurrentInstantiation() || SS.isInvalid())
 return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
   

[clang] [clang-tools-extra] [Clang][Sema] Diagnose current instantiation used as an incomplete base class (PR #92597)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92597

>From 4a535c2f2660583487018f421788cd2b88d8428d Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Fri, 17 May 2024 13:30:04 -0400
Subject: [PATCH 1/8] [Clang][Sema] Diagnose current instantiation used a
 incomplete base class

---
 clang/lib/AST/Type.cpp|   4 +
 clang/lib/Sema/SemaDeclCXX.cpp| 116 +-
 .../basic.lookup.qual/class.qual/p2.cpp   |  10 +-
 clang/test/SemaTemplate/dependent-names.cpp   |   9 +-
 .../test/SemaTemplate/destructor-template.cpp |  14 ++-
 .../test/SemaTemplate/typo-dependent-name.cpp |   7 +-
 6 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e31741cd44240..4ad764b67f81f 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2372,6 +2372,10 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
   *Def = Rec;
 return !Rec->isCompleteDefinition();
   }
+  case InjectedClassName: {
+CXXRecordDecl *Rec = cast(CanonicalType)->getDecl();
+return Rec->isBeingDefined();
+  }
   case ConstantArray:
   case VariableArray:
 // An array is incomplete if its element type is incomplete
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8225381985052..84033a602f131 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2704,28 +2704,53 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 Access = AS_public;
 
   QualType BaseType = TInfo->getType();
+  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
   if (BaseType->containsErrors()) {
 // Already emitted a diagnostic when parsing the error type.
 return nullptr;
   }
-  // C++ [class.union]p1:
-  //   A union shall not have base classes.
-  if (Class->isUnion()) {
-Diag(Class->getLocation(), diag::err_base_clause_on_union)
-  << SpecifierRange;
-return nullptr;
-  }
 
-  if (EllipsisLoc.isValid() &&
-  !TInfo->getType()->containsUnexpandedParameterPack()) {
+  if (EllipsisLoc.isValid() && !BaseType->containsUnexpandedParameterPack()) {
 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
   << TInfo->getTypeLoc().getSourceRange();
 EllipsisLoc = SourceLocation();
   }
 
-  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
+  auto *BaseDecl =
+  dyn_cast_if_present(computeDeclContext(BaseType));
+  // C++ [class.derived.general]p2:
+  //   A class-or-decltype shall denote a (possibly cv-qualified) class type
+  //   that is not an incompletely defined class; any cv-qualifiers are
+  //   ignored.
+  if (BaseDecl) {
+// C++ [class.union.general]p4:
+// [...]  A union shall not be used as a base class.
+if (BaseDecl->isUnion()) {
+  Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
+  return nullptr;
+}
+
+// For the MS ABI, propagate DLL attributes to base class templates.
+if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+Context.getTargetInfo().getTriple().isPS()) {
+  if (Attr *ClassAttr = getDLLAttr(Class)) {
+if (auto *BaseSpec =
+dyn_cast(BaseDecl)) {
+  propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseSpec,
+  BaseLoc);
+}
+  }
+}
 
-  if (BaseType->isDependentType()) {
+if (RequireCompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class,
+SpecifierRange)) {
+  Class->setInvalidDecl();
+  return nullptr;
+}
+  } else if (!BaseType->isDependentType()) {
+Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
+return nullptr;
+  } else {
 // Make sure that we don't have circular inheritance among our dependent
 // bases. For non-dependent bases, the check for completeness below handles
 // this.
@@ -2750,65 +2775,28 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 // constexpr evaluator). If this case happens (in errory-recovery mode), we
 // explicitly mark the Class decl invalid. The diagnostic was already
 // emitted.
-if (!Class->getTypeForDecl()->isDependentType())
+if (!Class->isDependentContext())
   Class->setInvalidDecl();
 return new (Context) CXXBaseSpecifier(
 SpecifierRange, Virtual, Class->getTagKind() == TagTypeKind::Class,
 Access, TInfo, EllipsisLoc);
   }
 
-  // Base specifiers must be record types.
-  if (!BaseType->isRecordType()) {
-Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // C++ [class.union]p1:
-  //   A union shall not be used as a base class.
-  if (BaseType->isUnionType()) {
-Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // For the MS ABI, propagate DLL attributes to base class templates.
-  if 

[clang] [clang-tools-extra] [Clang][Sema] Diagnose current instantiation used as an incomplete base class (PR #92597)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92597

>From 4a535c2f2660583487018f421788cd2b88d8428d Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Fri, 17 May 2024 13:30:04 -0400
Subject: [PATCH 1/7] [Clang][Sema] Diagnose current instantiation used a
 incomplete base class

---
 clang/lib/AST/Type.cpp|   4 +
 clang/lib/Sema/SemaDeclCXX.cpp| 116 +-
 .../basic.lookup.qual/class.qual/p2.cpp   |  10 +-
 clang/test/SemaTemplate/dependent-names.cpp   |   9 +-
 .../test/SemaTemplate/destructor-template.cpp |  14 ++-
 .../test/SemaTemplate/typo-dependent-name.cpp |   7 +-
 6 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e31741cd44240..4ad764b67f81f 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2372,6 +2372,10 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
   *Def = Rec;
 return !Rec->isCompleteDefinition();
   }
+  case InjectedClassName: {
+CXXRecordDecl *Rec = cast(CanonicalType)->getDecl();
+return Rec->isBeingDefined();
+  }
   case ConstantArray:
   case VariableArray:
 // An array is incomplete if its element type is incomplete
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8225381985052..84033a602f131 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2704,28 +2704,53 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 Access = AS_public;
 
   QualType BaseType = TInfo->getType();
+  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
   if (BaseType->containsErrors()) {
 // Already emitted a diagnostic when parsing the error type.
 return nullptr;
   }
-  // C++ [class.union]p1:
-  //   A union shall not have base classes.
-  if (Class->isUnion()) {
-Diag(Class->getLocation(), diag::err_base_clause_on_union)
-  << SpecifierRange;
-return nullptr;
-  }
 
-  if (EllipsisLoc.isValid() &&
-  !TInfo->getType()->containsUnexpandedParameterPack()) {
+  if (EllipsisLoc.isValid() && !BaseType->containsUnexpandedParameterPack()) {
 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
   << TInfo->getTypeLoc().getSourceRange();
 EllipsisLoc = SourceLocation();
   }
 
-  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
+  auto *BaseDecl =
+  dyn_cast_if_present(computeDeclContext(BaseType));
+  // C++ [class.derived.general]p2:
+  //   A class-or-decltype shall denote a (possibly cv-qualified) class type
+  //   that is not an incompletely defined class; any cv-qualifiers are
+  //   ignored.
+  if (BaseDecl) {
+// C++ [class.union.general]p4:
+// [...]  A union shall not be used as a base class.
+if (BaseDecl->isUnion()) {
+  Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
+  return nullptr;
+}
+
+// For the MS ABI, propagate DLL attributes to base class templates.
+if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+Context.getTargetInfo().getTriple().isPS()) {
+  if (Attr *ClassAttr = getDLLAttr(Class)) {
+if (auto *BaseSpec =
+dyn_cast(BaseDecl)) {
+  propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseSpec,
+  BaseLoc);
+}
+  }
+}
 
-  if (BaseType->isDependentType()) {
+if (RequireCompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class,
+SpecifierRange)) {
+  Class->setInvalidDecl();
+  return nullptr;
+}
+  } else if (!BaseType->isDependentType()) {
+Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
+return nullptr;
+  } else {
 // Make sure that we don't have circular inheritance among our dependent
 // bases. For non-dependent bases, the check for completeness below handles
 // this.
@@ -2750,65 +2775,28 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 // constexpr evaluator). If this case happens (in errory-recovery mode), we
 // explicitly mark the Class decl invalid. The diagnostic was already
 // emitted.
-if (!Class->getTypeForDecl()->isDependentType())
+if (!Class->isDependentContext())
   Class->setInvalidDecl();
 return new (Context) CXXBaseSpecifier(
 SpecifierRange, Virtual, Class->getTagKind() == TagTypeKind::Class,
 Access, TInfo, EllipsisLoc);
   }
 
-  // Base specifiers must be record types.
-  if (!BaseType->isRecordType()) {
-Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // C++ [class.union]p1:
-  //   A union shall not be used as a base class.
-  if (BaseType->isUnionType()) {
-Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // For the MS ABI, propagate DLL attributes to base class templates.
-  if 

[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92452

>From 613560033f7bf9acb9315766291bff07ee9e9b5f Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 16:42:27 -0400
Subject: [PATCH 1/3] [Clang][Sema] Fix crash when diagnosing near-match for
 'constexpr' redeclaration in C++11

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Sema/DeclSpec.h| 12 ++--
 clang/lib/Sema/SemaDecl.cpp| 18 +-
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp  | 11 +++
 4 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5a123b0b86dda..6f5cc58d2f9e1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -742,6 +742,8 @@ Bug Fixes to C++ Support
 - Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
 - Fix a bug where the last argument was not considered when considering the 
most viable function for
   explicit object argument member functions. Fixes (#GH92188).
+- Fix a C++11 crash when a non-const non-static member function is defined 
out-of-line with
+  the ``constexpr`` specifier.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..44d96db54b5f0 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
 
 /// Retrieve the location of the 'const' qualifier.
 SourceLocation getConstQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getConstSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'volatile' qualifier.
 SourceLocation getVolatileQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getVolatileSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getVolatileSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'restrict' qualifier.
 SourceLocation getRestrictQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getRestrictSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getRestrictSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'mutable' qualifier, if any.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 557fe10619c35..05575a837a409 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9217,15 +9217,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
+DB << 
FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
+ " const");
+  else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();
+   ConstLoc.isValid())
+DB << FixItHint::CreateRemoval(ConstLoc);
 } else
   SemaRef.Diag(FD->getLocation(),
IsMember ? diag::note_member_def_close_match
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a28a5f91c4775..788e93b56bb38 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -154,3 +154,14 @@ namespace {
   // FIXME: We should diagnose this prior to C++17.
   const int  = A::n;
 }
+
+#if __cplusplus < 201402L
+namespace ImplicitConstexprDef {
+  struct A {
+void f(); // expected-note {{member declaration does not match because it 
is not const qualified}}
+  };
+
+  constexpr void A::f() { } // expected-warning {{'constexpr' non-static 
member function 

[clang] [clang-tools-extra] [Clang][Sema] Diagnose current instantiation used as an incomplete base class (PR #92597)

2024-05-20 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92597

>From 4a535c2f2660583487018f421788cd2b88d8428d Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Fri, 17 May 2024 13:30:04 -0400
Subject: [PATCH 1/5] [Clang][Sema] Diagnose current instantiation used a
 incomplete base class

---
 clang/lib/AST/Type.cpp|   4 +
 clang/lib/Sema/SemaDeclCXX.cpp| 116 +-
 .../basic.lookup.qual/class.qual/p2.cpp   |  10 +-
 clang/test/SemaTemplate/dependent-names.cpp   |   9 +-
 .../test/SemaTemplate/destructor-template.cpp |  14 ++-
 .../test/SemaTemplate/typo-dependent-name.cpp |   7 +-
 6 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e31741cd44240..4ad764b67f81f 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2372,6 +2372,10 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
   *Def = Rec;
 return !Rec->isCompleteDefinition();
   }
+  case InjectedClassName: {
+CXXRecordDecl *Rec = cast(CanonicalType)->getDecl();
+return Rec->isBeingDefined();
+  }
   case ConstantArray:
   case VariableArray:
 // An array is incomplete if its element type is incomplete
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8225381985052..84033a602f131 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2704,28 +2704,53 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 Access = AS_public;
 
   QualType BaseType = TInfo->getType();
+  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
   if (BaseType->containsErrors()) {
 // Already emitted a diagnostic when parsing the error type.
 return nullptr;
   }
-  // C++ [class.union]p1:
-  //   A union shall not have base classes.
-  if (Class->isUnion()) {
-Diag(Class->getLocation(), diag::err_base_clause_on_union)
-  << SpecifierRange;
-return nullptr;
-  }
 
-  if (EllipsisLoc.isValid() &&
-  !TInfo->getType()->containsUnexpandedParameterPack()) {
+  if (EllipsisLoc.isValid() && !BaseType->containsUnexpandedParameterPack()) {
 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
   << TInfo->getTypeLoc().getSourceRange();
 EllipsisLoc = SourceLocation();
   }
 
-  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
+  auto *BaseDecl =
+  dyn_cast_if_present(computeDeclContext(BaseType));
+  // C++ [class.derived.general]p2:
+  //   A class-or-decltype shall denote a (possibly cv-qualified) class type
+  //   that is not an incompletely defined class; any cv-qualifiers are
+  //   ignored.
+  if (BaseDecl) {
+// C++ [class.union.general]p4:
+// [...]  A union shall not be used as a base class.
+if (BaseDecl->isUnion()) {
+  Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
+  return nullptr;
+}
+
+// For the MS ABI, propagate DLL attributes to base class templates.
+if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+Context.getTargetInfo().getTriple().isPS()) {
+  if (Attr *ClassAttr = getDLLAttr(Class)) {
+if (auto *BaseSpec =
+dyn_cast(BaseDecl)) {
+  propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseSpec,
+  BaseLoc);
+}
+  }
+}
 
-  if (BaseType->isDependentType()) {
+if (RequireCompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class,
+SpecifierRange)) {
+  Class->setInvalidDecl();
+  return nullptr;
+}
+  } else if (!BaseType->isDependentType()) {
+Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
+return nullptr;
+  } else {
 // Make sure that we don't have circular inheritance among our dependent
 // bases. For non-dependent bases, the check for completeness below handles
 // this.
@@ -2750,65 +2775,28 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 // constexpr evaluator). If this case happens (in errory-recovery mode), we
 // explicitly mark the Class decl invalid. The diagnostic was already
 // emitted.
-if (!Class->getTypeForDecl()->isDependentType())
+if (!Class->isDependentContext())
   Class->setInvalidDecl();
 return new (Context) CXXBaseSpecifier(
 SpecifierRange, Virtual, Class->getTagKind() == TagTypeKind::Class,
 Access, TInfo, EllipsisLoc);
   }
 
-  // Base specifiers must be record types.
-  if (!BaseType->isRecordType()) {
-Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // C++ [class.union]p1:
-  //   A union shall not be used as a base class.
-  if (BaseType->isUnionType()) {
-Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // For the MS ABI, propagate DLL attributes to base class templates.
-  if 

[clang] [clang-tools-extra] [Clang][Sema] Diagnose current instantiation used as an incomplete base class (PR #92597)

2024-05-17 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92597

>From 9d95d211797843f3dc612fe4340354b5fbf6a2fe Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Fri, 17 May 2024 13:30:04 -0400
Subject: [PATCH 1/5] [Clang][Sema] Diagnose current instantiation used a
 incomplete base class

---
 clang/lib/AST/Type.cpp|   4 +
 clang/lib/Sema/SemaDeclCXX.cpp| 116 +-
 .../basic.lookup.qual/class.qual/p2.cpp   |  10 +-
 clang/test/SemaTemplate/dependent-names.cpp   |   9 +-
 .../test/SemaTemplate/destructor-template.cpp |  14 ++-
 .../test/SemaTemplate/typo-dependent-name.cpp |   7 +-
 6 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e31741cd44240..4ad764b67f81f 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2372,6 +2372,10 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
   *Def = Rec;
 return !Rec->isCompleteDefinition();
   }
+  case InjectedClassName: {
+CXXRecordDecl *Rec = cast(CanonicalType)->getDecl();
+return Rec->isBeingDefined();
+  }
   case ConstantArray:
   case VariableArray:
 // An array is incomplete if its element type is incomplete
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8225381985052..84033a602f131 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2704,28 +2704,53 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 Access = AS_public;
 
   QualType BaseType = TInfo->getType();
+  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
   if (BaseType->containsErrors()) {
 // Already emitted a diagnostic when parsing the error type.
 return nullptr;
   }
-  // C++ [class.union]p1:
-  //   A union shall not have base classes.
-  if (Class->isUnion()) {
-Diag(Class->getLocation(), diag::err_base_clause_on_union)
-  << SpecifierRange;
-return nullptr;
-  }
 
-  if (EllipsisLoc.isValid() &&
-  !TInfo->getType()->containsUnexpandedParameterPack()) {
+  if (EllipsisLoc.isValid() && !BaseType->containsUnexpandedParameterPack()) {
 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
   << TInfo->getTypeLoc().getSourceRange();
 EllipsisLoc = SourceLocation();
   }
 
-  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
+  auto *BaseDecl =
+  dyn_cast_if_present(computeDeclContext(BaseType));
+  // C++ [class.derived.general]p2:
+  //   A class-or-decltype shall denote a (possibly cv-qualified) class type
+  //   that is not an incompletely defined class; any cv-qualifiers are
+  //   ignored.
+  if (BaseDecl) {
+// C++ [class.union.general]p4:
+// [...]  A union shall not be used as a base class.
+if (BaseDecl->isUnion()) {
+  Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
+  return nullptr;
+}
+
+// For the MS ABI, propagate DLL attributes to base class templates.
+if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+Context.getTargetInfo().getTriple().isPS()) {
+  if (Attr *ClassAttr = getDLLAttr(Class)) {
+if (auto *BaseSpec =
+dyn_cast(BaseDecl)) {
+  propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseSpec,
+  BaseLoc);
+}
+  }
+}
 
-  if (BaseType->isDependentType()) {
+if (RequireCompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class,
+SpecifierRange)) {
+  Class->setInvalidDecl();
+  return nullptr;
+}
+  } else if (!BaseType->isDependentType()) {
+Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
+return nullptr;
+  } else {
 // Make sure that we don't have circular inheritance among our dependent
 // bases. For non-dependent bases, the check for completeness below handles
 // this.
@@ -2750,65 +2775,28 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 // constexpr evaluator). If this case happens (in errory-recovery mode), we
 // explicitly mark the Class decl invalid. The diagnostic was already
 // emitted.
-if (!Class->getTypeForDecl()->isDependentType())
+if (!Class->isDependentContext())
   Class->setInvalidDecl();
 return new (Context) CXXBaseSpecifier(
 SpecifierRange, Virtual, Class->getTagKind() == TagTypeKind::Class,
 Access, TInfo, EllipsisLoc);
   }
 
-  // Base specifiers must be record types.
-  if (!BaseType->isRecordType()) {
-Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // C++ [class.union]p1:
-  //   A union shall not be used as a base class.
-  if (BaseType->isUnionType()) {
-Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
-return nullptr;
-  }
-
-  // For the MS ABI, propagate DLL attributes to base class templates.
-  if 

[clang] [Clang][Sema] Don't build CXXDependentScopeMemberExprs for potentially implicit class member access expressions (PR #92318)

2024-05-17 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92318

>From db264c719dfae25a536fb2452328d9aaeeea7b6f Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 15 May 2024 16:13:03 -0400
Subject: [PATCH 1/4] [Clang][Sema] Don't build CXXDependentScopeMemberExprs
 for potentially implicit class member access expressions

---
 clang/include/clang/Sema/Sema.h   | 11 +--
 clang/lib/Sema/SemaCXXScopeSpec.cpp   |  8 ++
 clang/lib/Sema/SemaExpr.cpp   | 31 ++
 clang/lib/Sema/SemaTemplate.cpp   | 98 ++-
 clang/lib/Sema/TreeTransform.h|  6 +-
 .../class.mfct/class.mfct.non-static/p3.cpp   | 91 -
 ...ms-function-specialization-class-scope.cpp | 52 ++
 .../ms-lookup-template-base-classes.cpp   | 12 +--
 .../ASTMatchers/ASTMatchersNodeTest.cpp   |  6 +-
 9 files changed, 206 insertions(+), 109 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index d4d4a82525a02..fcc60a2ee4bca 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5374,11 +5374,9 @@ class Sema final : public SemaBase {
   bool UseArgumentDependentLookup(const CXXScopeSpec , const LookupResult 
,
   bool HasTrailingLParen);
 
-  ExprResult
-  BuildQualifiedDeclarationNameExpr(CXXScopeSpec ,
-const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S,
-TypeSourceInfo **RecoveryTSI = nullptr);
+  ExprResult BuildQualifiedDeclarationNameExpr(
+  CXXScopeSpec , const DeclarationNameInfo ,
+  bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
 
   ExprResult BuildDeclarationNameExpr(const CXXScopeSpec , LookupResult ,
   bool NeedsADL,
@@ -8990,7 +8988,8 @@ class Sema final : public SemaBase {
   ExprResult
   BuildQualifiedTemplateIdExpr(CXXScopeSpec , SourceLocation TemplateKWLoc,
const DeclarationNameInfo ,
-   const TemplateArgumentListInfo *TemplateArgs);
+   const TemplateArgumentListInfo *TemplateArgs,
+   bool IsAddressOfOperand);
 
   TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec ,
  SourceLocation TemplateKWLoc,
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index fca5bd131bbc0..c405fbc0aa421 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -796,6 +796,14 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, 
NestedNameSpecInfo ,
 Diag(IdInfo.IdentifierLoc,
  diag::ext_undeclared_unqual_id_with_dependent_base)
 << IdInfo.Identifier << ContainingClass;
+// Fake up a nested-name-specifier that starts with the
+// injected-class-name of the enclosing class.
+QualType T = Context.getTypeDeclType(ContainingClass);
+TypeLocBuilder TLB;
+TLB.pushTrivial(Context, T, IdInfo.IdentifierLoc);
+SS.Extend(Context, /*TemplateKWLoc=*/SourceLocation(),
+  TLB.getTypeLocInContext(Context, T), IdInfo.IdentifierLoc);
+// Add the identifier to form a dependent name.
 SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc,
   IdInfo.CCLoc);
 return false;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5ecfdee21f09d..ebf02ae566044 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2946,26 +2946,14 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec ,
 /// this path.
 ExprResult Sema::BuildQualifiedDeclarationNameExpr(
 CXXScopeSpec , const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S, TypeSourceInfo **RecoveryTSI) {
-  if (NameInfo.getName().isDependentName())
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  DeclContext *DC = computeDeclContext(SS, false);
-  if (!DC)
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  if (RequireCompleteDeclContext(SS, DC))
-return ExprError();
-
+bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI) {
   LookupResult R(*this, NameInfo, LookupOrdinaryName);
-  LookupQualifiedName(R, DC);
+  LookupParsedName(R, /*S=*/nullptr, , /*ObjectType=*/QualType());
 
   if (R.isAmbiguous())
 return ExprError();
 
-  if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)
+  if (R.wasNotFoundInCurrentInstantiation() || SS.isInvalid())
 return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
   

[clang] [Clang][Sema] Fix lookup of dependent operator= named by using-declaration (PR #91503)

2024-05-17 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

Closing this for now; I'll return to this once we correctly handle dependent 
`operator=`.

https://github.com/llvm/llvm-project/pull/91503
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix lookup of dependent operator= named by using-declaration (PR #91503)

2024-05-17 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/91503
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-17 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92452

>From 187eb245484e21970ac55f05a78d3221f2f07f9a Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 16:42:27 -0400
Subject: [PATCH 1/3] [Clang][Sema] Fix crash when diagnosing near-match for
 'constexpr' redeclaration in C++11

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Sema/DeclSpec.h| 12 ++--
 clang/lib/Sema/SemaDecl.cpp| 18 +-
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp  | 11 +++
 4 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2f83f5c6d54e9..3c7e0572e837f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -758,6 +758,8 @@ Bug Fixes to C++ Support
 - Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
 - Fix a bug where the last argument was not considered when considering the 
most viable function for
   explicit object argument member functions. Fixes (#GH92188).
+- Fix a C++11 crash when a non-const non-static member function is defined 
out-of-line with
+  the ``constexpr`` specifier.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..44d96db54b5f0 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
 
 /// Retrieve the location of the 'const' qualifier.
 SourceLocation getConstQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getConstSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'volatile' qualifier.
 SourceLocation getVolatileQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getVolatileSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getVolatileSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'restrict' qualifier.
 SourceLocation getRestrictQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getRestrictSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getRestrictSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'mutable' qualifier, if any.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f2b9202255cd4..4a1d55ea44703 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9217,15 +9217,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
+DB << 
FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
+ " const");
+  else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();
+   ConstLoc.isValid())
+DB << FixItHint::CreateRemoval(ConstLoc);
 } else
   SemaRef.Diag(FD->getLocation(),
IsMember ? diag::note_member_def_close_match
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a28a5f91c4775..788e93b56bb38 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -154,3 +154,14 @@ namespace {
   // FIXME: We should diagnose this prior to C++17.
   const int  = A::n;
 }
+
+#if __cplusplus < 201402L
+namespace ImplicitConstexprDef {
+  struct A {
+void f(); // expected-note {{member declaration does not match because it 
is not const qualified}}
+  };
+
+  constexpr void A::f() { } // expected-warning {{'constexpr' non-static 
member function 

[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-17 Thread Krystian Stasiowski via cfe-commits


@@ -9203,15 +9203,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)

sdkrystian wrote:

I think it would work either way... since this is guarded by `if (FDisConst != 
NewFDisConst)`, `!NewFDisConst` implies `FDisConst`. 

https://github.com/llvm/llvm-project/pull/92452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose current instantiation used as an incomplete base class (PR #92597)

2024-05-17 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/92597

Consider the following:
```cpp
template
struct A
{
struct B : A { };
};
```
According to [[class.derived.general] 
p2](http://eel.is/c++draft/class.derived.general#2):
> [...] A _class-or-decltype_ shall denote a (possibly cv-qualified) class type 
> that is not an incompletely defined class; any cv-qualifiers are ignored. 
> [...]

Although GCC and EDG rejects this, Clang accepts it. This is incorrect, as `A` 
is incomplete within its own definition (outside of a complete-class context). 
This patch correctly diagnoses instances where the current instantiation is 
used as a base class before it is complete.

Conversely, Clang erroneously rejects the following:
```cpp
template
struct A 
{
struct B;

struct C : B { };

struct B : C { }; // error: circular inheritance between 'C' and 'A::B'
};
```
Though it may seem like no valid specialization of this template can be 
instantiated, an explicit specialization of either member classes for an 
implicit instantiated specialization of `A` would permit the definition of the 
other member class to be instantiated, e.g.:
```cpp
template<>
struct A::B { };

A::C c; // ok
```
So this patch also does away with this error. This means that circular 
inheritance is diagnosed during instantiation of the definition as a 
consequence of requiring the base class types to be complete (matching the 
behavior of GCC and EDG).


>From 9d95d211797843f3dc612fe4340354b5fbf6a2fe Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Fri, 17 May 2024 13:30:04 -0400
Subject: [PATCH 1/4] [Clang][Sema] Diagnose current instantiation used a
 incomplete base class

---
 clang/lib/AST/Type.cpp|   4 +
 clang/lib/Sema/SemaDeclCXX.cpp| 116 +-
 .../basic.lookup.qual/class.qual/p2.cpp   |  10 +-
 clang/test/SemaTemplate/dependent-names.cpp   |   9 +-
 .../test/SemaTemplate/destructor-template.cpp |  14 ++-
 .../test/SemaTemplate/typo-dependent-name.cpp |   7 +-
 6 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e31741cd44240..4ad764b67f81f 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2372,6 +2372,10 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
   *Def = Rec;
 return !Rec->isCompleteDefinition();
   }
+  case InjectedClassName: {
+CXXRecordDecl *Rec = cast(CanonicalType)->getDecl();
+return Rec->isBeingDefined();
+  }
   case ConstantArray:
   case VariableArray:
 // An array is incomplete if its element type is incomplete
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8225381985052..84033a602f131 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2704,28 +2704,53 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 Access = AS_public;
 
   QualType BaseType = TInfo->getType();
+  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
   if (BaseType->containsErrors()) {
 // Already emitted a diagnostic when parsing the error type.
 return nullptr;
   }
-  // C++ [class.union]p1:
-  //   A union shall not have base classes.
-  if (Class->isUnion()) {
-Diag(Class->getLocation(), diag::err_base_clause_on_union)
-  << SpecifierRange;
-return nullptr;
-  }
 
-  if (EllipsisLoc.isValid() &&
-  !TInfo->getType()->containsUnexpandedParameterPack()) {
+  if (EllipsisLoc.isValid() && !BaseType->containsUnexpandedParameterPack()) {
 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
   << TInfo->getTypeLoc().getSourceRange();
 EllipsisLoc = SourceLocation();
   }
 
-  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
+  auto *BaseDecl =
+  dyn_cast_if_present(computeDeclContext(BaseType));
+  // C++ [class.derived.general]p2:
+  //   A class-or-decltype shall denote a (possibly cv-qualified) class type
+  //   that is not an incompletely defined class; any cv-qualifiers are
+  //   ignored.
+  if (BaseDecl) {
+// C++ [class.union.general]p4:
+// [...]  A union shall not be used as a base class.
+if (BaseDecl->isUnion()) {
+  Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
+  return nullptr;
+}
+
+// For the MS ABI, propagate DLL attributes to base class templates.
+if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+Context.getTargetInfo().getTriple().isPS()) {
+  if (Attr *ClassAttr = getDLLAttr(Class)) {
+if (auto *BaseSpec =
+dyn_cast(BaseDecl)) {
+  propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseSpec,
+  BaseLoc);
+}
+  }
+}
 
-  if (BaseType->isDependentType()) {
+if (RequireCompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class,
+SpecifierRange)) {
+  

[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-17 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92452

>From 27fab1ec54259941e3ded174de18cd99aa89bf7e Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 16:42:27 -0400
Subject: [PATCH 1/3] [Clang][Sema] Fix crash when diagnosing near-match for
 'constexpr' redeclaration in C++11

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Sema/DeclSpec.h| 12 ++--
 clang/lib/Sema/SemaDecl.cpp| 18 +-
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp  | 11 +++
 4 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d2928e418623..411a5f752899d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -724,6 +724,8 @@ Bug Fixes to C++ Support
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
 - Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
+- Fix a C++11 crash when a non-const non-static member function is defined 
out-of-line with
+  the ``constexpr`` specifier.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..44d96db54b5f0 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
 
 /// Retrieve the location of the 'const' qualifier.
 SourceLocation getConstQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getConstSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'volatile' qualifier.
 SourceLocation getVolatileQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getVolatileSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getVolatileSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'restrict' qualifier.
 SourceLocation getRestrictQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getRestrictSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getRestrictSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'mutable' qualifier, if any.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0dbdf923df95a..22749dc4799bc 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9203,15 +9203,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
+DB << 
FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
+ " const");
+  else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();
+   ConstLoc.isValid())
+DB << FixItHint::CreateRemoval(ConstLoc);
 } else
   SemaRef.Diag(FD->getLocation(),
IsMember ? diag::note_member_def_close_match
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a28a5f91c4775..788e93b56bb38 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -154,3 +154,14 @@ namespace {
   // FIXME: We should diagnose this prior to C++17.
   const int  = A::n;
 }
+
+#if __cplusplus < 201402L
+namespace ImplicitConstexprDef {
+  struct A {
+void f(); // expected-note {{member declaration does not match because it 
is not const qualified}}
+  };
+
+  constexpr void A::f() { } // expected-warning {{'constexpr' non-static 
member function will not be 

[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-17 Thread Krystian Stasiowski via cfe-commits


@@ -724,6 +724,8 @@ Bug Fixes to C++ Support
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
 - Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
+- Fix a C++11 crash when a non-const non-static member function is defined 
out-of-line with

sdkrystian wrote:

Nevermind, I did :) #61004

https://github.com/llvm/llvm-project/pull/92452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-17 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92452

>From 27fab1ec54259941e3ded174de18cd99aa89bf7e Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 16:42:27 -0400
Subject: [PATCH 1/2] [Clang][Sema] Fix crash when diagnosing near-match for
 'constexpr' redeclaration in C++11

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Sema/DeclSpec.h| 12 ++--
 clang/lib/Sema/SemaDecl.cpp| 18 +-
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp  | 11 +++
 4 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d2928e418623..411a5f752899d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -724,6 +724,8 @@ Bug Fixes to C++ Support
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
 - Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
+- Fix a C++11 crash when a non-const non-static member function is defined 
out-of-line with
+  the ``constexpr`` specifier.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..44d96db54b5f0 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
 
 /// Retrieve the location of the 'const' qualifier.
 SourceLocation getConstQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getConstSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'volatile' qualifier.
 SourceLocation getVolatileQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getVolatileSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getVolatileSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'restrict' qualifier.
 SourceLocation getRestrictQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getRestrictSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getRestrictSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'mutable' qualifier, if any.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0dbdf923df95a..22749dc4799bc 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9203,15 +9203,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
+DB << 
FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
+ " const");
+  else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();
+   ConstLoc.isValid())
+DB << FixItHint::CreateRemoval(ConstLoc);
 } else
   SemaRef.Diag(FD->getLocation(),
IsMember ? diag::note_member_def_close_match
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a28a5f91c4775..788e93b56bb38 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -154,3 +154,14 @@ namespace {
   // FIXME: We should diagnose this prior to C++17.
   const int  = A::n;
 }
+
+#if __cplusplus < 201402L
+namespace ImplicitConstexprDef {
+  struct A {
+void f(); // expected-note {{member declaration does not match because it 
is not const qualified}}
+  };
+
+  constexpr void A::f() { } // expected-warning {{'constexpr' non-static 
member function will not be 

[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-17 Thread Krystian Stasiowski via cfe-commits


@@ -724,6 +724,8 @@ Bug Fixes to C++ Support
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
 - Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
+- Fix a C++11 crash when a non-const non-static member function is defined 
out-of-line with

sdkrystian wrote:

I looked, but couldn't find any

https://github.com/llvm/llvm-project/pull/92452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-17 Thread Krystian Stasiowski via cfe-commits


@@ -9203,15 +9203,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
+DB << 
FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
+ " const");
+  else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();

sdkrystian wrote:

Fair enough :)

https://github.com/llvm/llvm-project/pull/92452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-17 Thread Krystian Stasiowski via cfe-commits


@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
 
 /// Retrieve the location of the 'const' qualifier.
 SourceLocation getConstQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getConstSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()

sdkrystian wrote:

@AaronBallman Updated

https://github.com/llvm/llvm-project/pull/92452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-17 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92452

>From 27fab1ec54259941e3ded174de18cd99aa89bf7e Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 16:42:27 -0400
Subject: [PATCH 1/2] [Clang][Sema] Fix crash when diagnosing near-match for
 'constexpr' redeclaration in C++11

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Sema/DeclSpec.h| 12 ++--
 clang/lib/Sema/SemaDecl.cpp| 18 +-
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp  | 11 +++
 4 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d2928e418623..411a5f752899d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -724,6 +724,8 @@ Bug Fixes to C++ Support
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
 - Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
+- Fix a C++11 crash when a non-const non-static member function is defined 
out-of-line with
+  the ``constexpr`` specifier.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..44d96db54b5f0 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
 
 /// Retrieve the location of the 'const' qualifier.
 SourceLocation getConstQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getConstSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'volatile' qualifier.
 SourceLocation getVolatileQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getVolatileSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getVolatileSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'restrict' qualifier.
 SourceLocation getRestrictQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getRestrictSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getRestrictSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'mutable' qualifier, if any.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0dbdf923df95a..22749dc4799bc 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9203,15 +9203,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
+DB << 
FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
+ " const");
+  else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();
+   ConstLoc.isValid())
+DB << FixItHint::CreateRemoval(ConstLoc);
 } else
   SemaRef.Diag(FD->getLocation(),
IsMember ? diag::note_member_def_close_match
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a28a5f91c4775..788e93b56bb38 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -154,3 +154,14 @@ namespace {
   // FIXME: We should diagnose this prior to C++17.
   const int  = A::n;
 }
+
+#if __cplusplus < 201402L
+namespace ImplicitConstexprDef {
+  struct A {
+void f(); // expected-note {{member declaration does not match because it 
is not const qualified}}
+  };
+
+  constexpr void A::f() { } // expected-warning {{'constexpr' non-static 
member function will not be 

[clang] [Clang][Sema] Don't build CXXDependentScopeMemberExprs for potentially implicit class member access expressions (PR #92318)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92318

>From 4ae259b21661caae2a9cd89437c56f3915195682 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 15 May 2024 16:13:03 -0400
Subject: [PATCH 1/4] [Clang][Sema] Don't build CXXDependentScopeMemberExprs
 for potentially implicit class member access expressions

---
 clang/include/clang/Sema/Sema.h   | 11 +--
 clang/lib/Sema/SemaCXXScopeSpec.cpp   |  8 ++
 clang/lib/Sema/SemaExpr.cpp   | 31 ++
 clang/lib/Sema/SemaTemplate.cpp   | 98 ++-
 clang/lib/Sema/TreeTransform.h|  6 +-
 .../class.mfct/class.mfct.non-static/p3.cpp   | 91 -
 ...ms-function-specialization-class-scope.cpp | 52 ++
 .../ms-lookup-template-base-classes.cpp   | 12 +--
 .../ASTMatchers/ASTMatchersNodeTest.cpp   |  6 +-
 9 files changed, 206 insertions(+), 109 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 66d5e2d4a4ade..c35cb815fdfeb 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5366,11 +5366,9 @@ class Sema final : public SemaBase {
   bool UseArgumentDependentLookup(const CXXScopeSpec , const LookupResult 
,
   bool HasTrailingLParen);
 
-  ExprResult
-  BuildQualifiedDeclarationNameExpr(CXXScopeSpec ,
-const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S,
-TypeSourceInfo **RecoveryTSI = nullptr);
+  ExprResult BuildQualifiedDeclarationNameExpr(
+  CXXScopeSpec , const DeclarationNameInfo ,
+  bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
 
   ExprResult BuildDeclarationNameExpr(const CXXScopeSpec , LookupResult ,
   bool NeedsADL,
@@ -8982,7 +8980,8 @@ class Sema final : public SemaBase {
   ExprResult
   BuildQualifiedTemplateIdExpr(CXXScopeSpec , SourceLocation TemplateKWLoc,
const DeclarationNameInfo ,
-   const TemplateArgumentListInfo *TemplateArgs);
+   const TemplateArgumentListInfo *TemplateArgs,
+   bool IsAddressOfOperand);
 
   TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec ,
  SourceLocation TemplateKWLoc,
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index fca5bd131bbc0..c405fbc0aa421 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -796,6 +796,14 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, 
NestedNameSpecInfo ,
 Diag(IdInfo.IdentifierLoc,
  diag::ext_undeclared_unqual_id_with_dependent_base)
 << IdInfo.Identifier << ContainingClass;
+// Fake up a nested-name-specifier that starts with the
+// injected-class-name of the enclosing class.
+QualType T = Context.getTypeDeclType(ContainingClass);
+TypeLocBuilder TLB;
+TLB.pushTrivial(Context, T, IdInfo.IdentifierLoc);
+SS.Extend(Context, /*TemplateKWLoc=*/SourceLocation(),
+  TLB.getTypeLocInContext(Context, T), IdInfo.IdentifierLoc);
+// Add the identifier to form a dependent name.
 SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc,
   IdInfo.CCLoc);
 return false;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 274e1fb183534..0e42501ea8ce2 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2946,26 +2946,14 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec ,
 /// this path.
 ExprResult Sema::BuildQualifiedDeclarationNameExpr(
 CXXScopeSpec , const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S, TypeSourceInfo **RecoveryTSI) {
-  if (NameInfo.getName().isDependentName())
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  DeclContext *DC = computeDeclContext(SS, false);
-  if (!DC)
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  if (RequireCompleteDeclContext(SS, DC))
-return ExprError();
-
+bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI) {
   LookupResult R(*this, NameInfo, LookupOrdinaryName);
-  LookupQualifiedName(R, DC);
+  LookupParsedName(R, /*S=*/nullptr, , /*ObjectType=*/QualType());
 
   if (R.isAmbiguous())
 return ExprError();
 
-  if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)
+  if (R.wasNotFoundInCurrentInstantiation() || SS.isInvalid())
 return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
   

[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-16 Thread Krystian Stasiowski via cfe-commits


@@ -9203,15 +9203,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
+DB << 
FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
+ " const");
+  else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();

sdkrystian wrote:

I opted for the "return `SourceLocation()` if no `const` qualifier is present" 
approach because it doesn't require the caller to check 
`hasMethodTypeQualifiers()` prior to calling `getConstQualifierLoc()`. Makes it 
less prone to being the cause of future crashes :)

https://github.com/llvm/llvm-project/pull/92452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-16 Thread Krystian Stasiowski via cfe-commits


@@ -9203,15 +9203,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)

sdkrystian wrote:

Er, no. We want to suggest removing `const` when `NewFDisConst` is `true`, or 
suggest inserting it if `false`. 

https://github.com/llvm/llvm-project/pull/92452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-16 Thread Krystian Stasiowski via cfe-commits


@@ -724,6 +724,8 @@ Bug Fixes to C++ Support
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
 - Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
+- Fix a C++11 crash when a non-const non-static member function is defined 
out-of-line with

sdkrystian wrote:

Don't know, I just happened upon it when working on #92449... I'll check

https://github.com/llvm/llvm-project/pull/92452
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Do not add implicit 'const' when matching constexpr function template explicit specializations after C++14 (PR #92449)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92449

>From b56eeb2ef435f06764bac0b062a8a0e747f697d4 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 15:47:04 -0400
Subject: [PATCH 1/2] [Clang][Sema] Do not add implicit 'const' when matching
 constexpr function template explicit specializations after C++14

---
 clang/lib/Sema/SemaTemplate.cpp   | 15 ++--
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 13 +++-
 .../CXX/temp/temp.spec/temp.expl.spec/p12.cpp | 70 +++
 3 files changed, 90 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index a5350ceb59cb7..420bd2de88686 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -10282,15 +10282,20 @@ bool Sema::CheckFunctionTemplateSpecialization(
 Ovl->getDeclContext()->getRedeclContext()))
 continue;
 
+  QualType FT = FD->getType();
+  // C++11 [dcl.constexpr]p8:
+  //   A constexpr specifier for a non-static member function that is not
+  //   a constructor declares that member function to be const.
+  //
   // When matching a constexpr member function template specialization
   // against the primary template, we don't yet know whether the
   // specialization has an implicit 'const' (because we don't know whether
   // it will be a static member function until we know which template it
-  // specializes), so adjust it now assuming it specializes this template.
-  QualType FT = FD->getType();
-  if (FD->isConstexpr()) {
-CXXMethodDecl *OldMD =
-  dyn_cast(FunTmpl->getTemplatedDecl());
+  // specializes). This rule was removed in C++14.
+  if (auto *NewMD = dyn_cast(FD);
+  !getLangOpts().CPlusPlus14 && NewMD && NewMD->isConstexpr() &&
+  !isa(NewMD)) {
+auto *OldMD = dyn_cast(FunTmpl->getTemplatedDecl());
 if (OldMD && OldMD->isConst()) {
   const FunctionProtoType *FPT = FT->castAs();
   FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a28a5f91c4775..2712f203bbd76 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -89,6 +89,9 @@ struct S {
   template constexpr T f(); // expected-warning 0-1{{C++14}} 
expected-note 0-1{{candidate}}
   template 
   T g() const; // expected-note-re {{candidate template ignored: could not 
match 'T (){{( __attribute__\(\(thiscall\)\))?}} const' against 'char (){{( 
__attribute__\(\(thiscall\)\))?}}'}}
+#if __cplusplus >= 201402L
+  // expected-note@-2 {{candidate template ignored: could not match 'T () 
const' against 'int ()'}}
+#endif
 };
 
 // explicit specialization can differ in constepxr
@@ -100,13 +103,17 @@ template <> notlit S::f() const { return notlit(); }
 #if __cplusplus >= 201402L
 // expected-error@-2 {{no function template matches}}
 #endif
-template <> constexpr int S::g() { return 0; } // expected-note {{previous}}
+template <> constexpr int S::g() { return 0; }
 #if __cplusplus < 201402L
 // expected-warning@-2 {{C++14}}
+// expected-note@-3 {{previous}}
 #else
-// expected-error@-4 {{does not match any declaration in 'S'}}
+// expected-error@-5 {{no function template matches function template 
specialization 'g'}}
+#endif
+template <> int S::g() const;
+#if __cplusplus < 201402L
+// expected-error@-2 {{non-constexpr declaration of 'g' follows constexpr 
declaration}}
 #endif
-template <> int S::g() const; // expected-error {{non-constexpr declaration of 
'g' follows constexpr declaration}}
 // specializations can drop the 'constexpr' but not the implied 'const'.
 template <> char S::g() { return 0; } // expected-error {{no function template 
matches}}
 template <> double S::g() const { return 0; } // ok
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp 
b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
new file mode 100644
index 0..2a57489083695
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify=expected,cxx11 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify=expected,since-cxx14 %s
+
+struct A {
+  template
+  void f0();
+
+  template<>
+  constexpr void f0(); // cxx11-error {{conflicting types for 'f0'}}
+  // cxx11-note@-1 {{previous declaration is here}}
+  // cxx11-warning@-2 {{'constexpr' non-static 
member function will not be implicitly 'const' in C++14; add 'const'}}
+
+  template
+  void f1() const; // since-cxx14-note 2{{candidate template ignored: could 
not match 'void () const' against 

[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/92452

Clang crashes when diagnosing the following invalid redeclaration in C++11:
```cpp
struct A {
  void f();
};

constexpr void A::f() { } // crash here
```
This happens because `DiagnoseInvalidRedeclaration` tries to create a fix-it to 
remove `const` from the out-of-line declaration of `f`, but there is no 
`SourceLocation` for the `const` qualifier (it's implicitly `const` due to 
`constexpr`) and an assert in `FunctionTypeInfo::getConstQualifierLoc` fails. 

This patch changes the accessors for _cv-qualifier-seq_ `SourceLocations` in 
`FunctionTypeInfo` to return an invalid `SourceLocation` if no 
_cv-qualifier-seq_ is present, and changes `DiagnoseInvalidRedeclaration` to 
only suggest the removal of the `const` qualifier when it was explicitly 
specified. 

>From 27fab1ec54259941e3ded174de18cd99aa89bf7e Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 16:42:27 -0400
Subject: [PATCH] [Clang][Sema] Fix crash when diagnosing near-match for
 'constexpr' redeclaration in C++11

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/include/clang/Sema/DeclSpec.h| 12 ++--
 clang/lib/Sema/SemaDecl.cpp| 18 +-
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp  | 11 +++
 4 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d2928e418623..411a5f752899d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -724,6 +724,8 @@ Bug Fixes to C++ Support
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
 - Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
+- Fix a C++11 crash when a non-const non-static member function is defined 
out-of-line with
+  the ``constexpr`` specifier.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..44d96db54b5f0 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
 
 /// Retrieve the location of the 'const' qualifier.
 SourceLocation getConstQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getConstSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'volatile' qualifier.
 SourceLocation getVolatileQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getVolatileSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getVolatileSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'restrict' qualifier.
 SourceLocation getRestrictQualifierLoc() const {
-  assert(MethodQualifiers);
-  return MethodQualifiers->getRestrictSpecLoc();
+  return MethodQualifiers ? MethodQualifiers->getRestrictSpecLoc()
+  : SourceLocation();
 }
 
 /// Retrieve the location of the 'mutable' qualifier, if any.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0dbdf923df95a..22749dc4799bc 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9203,15 +9203,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
 << Idx << FDParam->getType()
 << NewFD->getParamDecl(Idx - 1)->getType();
 } else if (FDisConst != NewFDisConst) {
-  SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
-  << NewFDisConst << FD->getSourceRange().getEnd()
-  << (NewFDisConst
-  ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
-  : 
FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
-   .getRParenLoc()
-   .getLocWithOffset(1),
-   " const"));
+  auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+<< NewFDisConst << FD->getSourceRange().getEnd();
+  if (const auto  = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
+DB << 
FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
+ " const");
+  else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();
+   ConstLoc.isValid())
+DB << FixItHint::CreateRemoval(ConstLoc);
 } else
   

[clang] [Clang][Sema] Do not add implicit 'const' when matching constexpr function template explicit specializations after C++14 (PR #92449)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92449

>From b56eeb2ef435f06764bac0b062a8a0e747f697d4 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 15:47:04 -0400
Subject: [PATCH 1/2] [Clang][Sema] Do not add implicit 'const' when matching
 constexpr function template explicit specializations after C++14

---
 clang/lib/Sema/SemaTemplate.cpp   | 15 ++--
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 13 +++-
 .../CXX/temp/temp.spec/temp.expl.spec/p12.cpp | 70 +++
 3 files changed, 90 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index a5350ceb59cb7..420bd2de88686 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -10282,15 +10282,20 @@ bool Sema::CheckFunctionTemplateSpecialization(
 Ovl->getDeclContext()->getRedeclContext()))
 continue;
 
+  QualType FT = FD->getType();
+  // C++11 [dcl.constexpr]p8:
+  //   A constexpr specifier for a non-static member function that is not
+  //   a constructor declares that member function to be const.
+  //
   // When matching a constexpr member function template specialization
   // against the primary template, we don't yet know whether the
   // specialization has an implicit 'const' (because we don't know whether
   // it will be a static member function until we know which template it
-  // specializes), so adjust it now assuming it specializes this template.
-  QualType FT = FD->getType();
-  if (FD->isConstexpr()) {
-CXXMethodDecl *OldMD =
-  dyn_cast(FunTmpl->getTemplatedDecl());
+  // specializes). This rule was removed in C++14.
+  if (auto *NewMD = dyn_cast(FD);
+  !getLangOpts().CPlusPlus14 && NewMD && NewMD->isConstexpr() &&
+  !isa(NewMD)) {
+auto *OldMD = dyn_cast(FunTmpl->getTemplatedDecl());
 if (OldMD && OldMD->isConst()) {
   const FunctionProtoType *FPT = FT->castAs();
   FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a28a5f91c4775..2712f203bbd76 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -89,6 +89,9 @@ struct S {
   template constexpr T f(); // expected-warning 0-1{{C++14}} 
expected-note 0-1{{candidate}}
   template 
   T g() const; // expected-note-re {{candidate template ignored: could not 
match 'T (){{( __attribute__\(\(thiscall\)\))?}} const' against 'char (){{( 
__attribute__\(\(thiscall\)\))?}}'}}
+#if __cplusplus >= 201402L
+  // expected-note@-2 {{candidate template ignored: could not match 'T () 
const' against 'int ()'}}
+#endif
 };
 
 // explicit specialization can differ in constepxr
@@ -100,13 +103,17 @@ template <> notlit S::f() const { return notlit(); }
 #if __cplusplus >= 201402L
 // expected-error@-2 {{no function template matches}}
 #endif
-template <> constexpr int S::g() { return 0; } // expected-note {{previous}}
+template <> constexpr int S::g() { return 0; }
 #if __cplusplus < 201402L
 // expected-warning@-2 {{C++14}}
+// expected-note@-3 {{previous}}
 #else
-// expected-error@-4 {{does not match any declaration in 'S'}}
+// expected-error@-5 {{no function template matches function template 
specialization 'g'}}
+#endif
+template <> int S::g() const;
+#if __cplusplus < 201402L
+// expected-error@-2 {{non-constexpr declaration of 'g' follows constexpr 
declaration}}
 #endif
-template <> int S::g() const; // expected-error {{non-constexpr declaration of 
'g' follows constexpr declaration}}
 // specializations can drop the 'constexpr' but not the implied 'const'.
 template <> char S::g() { return 0; } // expected-error {{no function template 
matches}}
 template <> double S::g() const { return 0; } // ok
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp 
b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
new file mode 100644
index 0..2a57489083695
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify=expected,cxx11 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify=expected,since-cxx14 %s
+
+struct A {
+  template
+  void f0();
+
+  template<>
+  constexpr void f0(); // cxx11-error {{conflicting types for 'f0'}}
+  // cxx11-note@-1 {{previous declaration is here}}
+  // cxx11-warning@-2 {{'constexpr' non-static 
member function will not be implicitly 'const' in C++14; add 'const'}}
+
+  template
+  void f1() const; // since-cxx14-note 2{{candidate template ignored: could 
not match 'void () const' against 

[clang] [Clang][Sema] Do not add implicit 'const' when matching constexpr function template explicit specializations after C++14 (PR #92449)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/92449

Clang incorrectly accepts the following when using C++14 or later:
```cpp
struct A {
  template
  void f() const;

  template<>
  constexpr void f();
};
```
Non-static member functions declared `constexpr` are only implicitly `const` in 
C++11. This patch makes clang reject the explicit specialization of `f` when 
using language standards after C++11.

>From b56eeb2ef435f06764bac0b062a8a0e747f697d4 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 15:47:04 -0400
Subject: [PATCH] [Clang][Sema] Do not add implicit 'const' when matching
 constexpr function template explicit specializations after C++14

---
 clang/lib/Sema/SemaTemplate.cpp   | 15 ++--
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 13 +++-
 .../CXX/temp/temp.spec/temp.expl.spec/p12.cpp | 70 +++
 3 files changed, 90 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index a5350ceb59cb7..420bd2de88686 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -10282,15 +10282,20 @@ bool Sema::CheckFunctionTemplateSpecialization(
 Ovl->getDeclContext()->getRedeclContext()))
 continue;
 
+  QualType FT = FD->getType();
+  // C++11 [dcl.constexpr]p8:
+  //   A constexpr specifier for a non-static member function that is not
+  //   a constructor declares that member function to be const.
+  //
   // When matching a constexpr member function template specialization
   // against the primary template, we don't yet know whether the
   // specialization has an implicit 'const' (because we don't know whether
   // it will be a static member function until we know which template it
-  // specializes), so adjust it now assuming it specializes this template.
-  QualType FT = FD->getType();
-  if (FD->isConstexpr()) {
-CXXMethodDecl *OldMD =
-  dyn_cast(FunTmpl->getTemplatedDecl());
+  // specializes). This rule was removed in C++14.
+  if (auto *NewMD = dyn_cast(FD);
+  !getLangOpts().CPlusPlus14 && NewMD && NewMD->isConstexpr() &&
+  !isa(NewMD)) {
+auto *OldMD = dyn_cast(FunTmpl->getTemplatedDecl());
 if (OldMD && OldMD->isConst()) {
   const FunctionProtoType *FPT = FT->castAs();
   FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a28a5f91c4775..2712f203bbd76 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -89,6 +89,9 @@ struct S {
   template constexpr T f(); // expected-warning 0-1{{C++14}} 
expected-note 0-1{{candidate}}
   template 
   T g() const; // expected-note-re {{candidate template ignored: could not 
match 'T (){{( __attribute__\(\(thiscall\)\))?}} const' against 'char (){{( 
__attribute__\(\(thiscall\)\))?}}'}}
+#if __cplusplus >= 201402L
+  // expected-note@-2 {{candidate template ignored: could not match 'T () 
const' against 'int ()'}}
+#endif
 };
 
 // explicit specialization can differ in constepxr
@@ -100,13 +103,17 @@ template <> notlit S::f() const { return notlit(); }
 #if __cplusplus >= 201402L
 // expected-error@-2 {{no function template matches}}
 #endif
-template <> constexpr int S::g() { return 0; } // expected-note {{previous}}
+template <> constexpr int S::g() { return 0; }
 #if __cplusplus < 201402L
 // expected-warning@-2 {{C++14}}
+// expected-note@-3 {{previous}}
 #else
-// expected-error@-4 {{does not match any declaration in 'S'}}
+// expected-error@-5 {{no function template matches function template 
specialization 'g'}}
+#endif
+template <> int S::g() const;
+#if __cplusplus < 201402L
+// expected-error@-2 {{non-constexpr declaration of 'g' follows constexpr 
declaration}}
 #endif
-template <> int S::g() const; // expected-error {{non-constexpr declaration of 
'g' follows constexpr declaration}}
 // specializations can drop the 'constexpr' but not the implied 'const'.
 template <> char S::g() { return 0; } // expected-error {{no function template 
matches}}
 template <> double S::g() const { return 0; } // ok
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp 
b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
new file mode 100644
index 0..2a57489083695
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p12.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify=expected,cxx11 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify=expected,since-cxx14 %s
+
+struct A {
+  template
+  void f0();
+
+  template<>
+  constexpr void f0(); // cxx11-error {{conflicting types for 'f0'}}
+ 

[clang] [Clang][Sema] ASTContext::getUnconstrainedType propagates dependence (PR #92425)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/92425
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] ASTContext::getUnconstrainedType propagates dependence (PR #92425)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92425

>From c26365ef78366b5c200d085ddc4211db1b2054e0 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 10:59:03 -0400
Subject: [PATCH 1/3] [Clang][Sema] ASTContext::getUnconstrainedType propagates
 dependence

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/AST/ASTContext.cpp  |  3 ++-
 .../temp/temp.decls/temp.fct/temp.func.order/p2.cpp   | 11 +++
 3 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 
clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index be4cded276321..21f273cf8f54e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -723,6 +723,7 @@ Bug Fixes to C++ Support
 - Clang now ignores template parameters only used within the exception 
specification of candidate function
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
+- Fix a bug with checking constrained non-type template parameters for 
equivalence.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 4475f399a120b..8fc2bb8c401c2 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5910,7 +5910,8 @@ QualType ASTContext::getUnconstrainedType(QualType T) 
const {
   if (auto *AT = CanonT->getAs()) {
 if (!AT->isConstrained())
   return T;
-return getQualifiedType(getAutoType(QualType(), AT->getKeyword(), false,
+return getQualifiedType(getAutoType(QualType(), AT->getKeyword(),
+AT->isDependentType(),
 AT->containsUnexpandedParameterPack()),
 T.getQualifiers());
   }
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp 
b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
new file mode 100644
index 0..ca753ec0c2d06
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// expected-no-diagnostics
+
+template
+concept C = sizeof(T) == sizeof(int);
+
+template
+struct A;
+
+template
+struct A;

>From 20554c70c5fc3e6f026bc6dcc9f6d8204d2e7a4a Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 12:34:39 -0400
Subject: [PATCH 2/3] [FOLD] add issue number to release note

---
 clang/docs/ReleaseNotes.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 21f273cf8f54e..2d2928e418623 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -723,7 +723,7 @@ Bug Fixes to C++ Support
 - Clang now ignores template parameters only used within the exception 
specification of candidate function
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
-- Fix a bug with checking constrained non-type template parameters for 
equivalence.
+- Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
 
 Bug Fixes to AST Handling
 ^

>From b472d4231a130671e7e32d8318f988c40b064eff Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 13:58:30 -0400
Subject: [PATCH 3/3] [FOLD] address review comments

---
 .../temp.decls/temp.fct/temp.func.order/p2.cpp | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp 
b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
index ca753ec0c2d06..df1bbd5fe8128 100644
--- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
@@ -1,11 +1,13 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
 // expected-no-diagnostics
 
-template
-concept C = sizeof(T) == sizeof(int);
+namespace GH77377 {
+  template
+  concept C = sizeof(T) == sizeof(int);
 
-template
-struct A;
+  template
+  struct A;
 
-template
-struct A;
+  template
+  struct A;
+}

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


[clang] [Clang][Sema] ASTContext::getUnconstrainedType propagates dependence (PR #92425)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92425

>From c26365ef78366b5c200d085ddc4211db1b2054e0 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 10:59:03 -0400
Subject: [PATCH 1/2] [Clang][Sema] ASTContext::getUnconstrainedType propagates
 dependence

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/AST/ASTContext.cpp  |  3 ++-
 .../temp/temp.decls/temp.fct/temp.func.order/p2.cpp   | 11 +++
 3 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 
clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index be4cded276321..21f273cf8f54e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -723,6 +723,7 @@ Bug Fixes to C++ Support
 - Clang now ignores template parameters only used within the exception 
specification of candidate function
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
+- Fix a bug with checking constrained non-type template parameters for 
equivalence.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 4475f399a120b..8fc2bb8c401c2 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5910,7 +5910,8 @@ QualType ASTContext::getUnconstrainedType(QualType T) 
const {
   if (auto *AT = CanonT->getAs()) {
 if (!AT->isConstrained())
   return T;
-return getQualifiedType(getAutoType(QualType(), AT->getKeyword(), false,
+return getQualifiedType(getAutoType(QualType(), AT->getKeyword(),
+AT->isDependentType(),
 AT->containsUnexpandedParameterPack()),
 T.getQualifiers());
   }
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp 
b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
new file mode 100644
index 0..ca753ec0c2d06
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// expected-no-diagnostics
+
+template
+concept C = sizeof(T) == sizeof(int);
+
+template
+struct A;
+
+template
+struct A;

>From 20554c70c5fc3e6f026bc6dcc9f6d8204d2e7a4a Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 12:34:39 -0400
Subject: [PATCH 2/2] [FOLD] add issue number to release note

---
 clang/docs/ReleaseNotes.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 21f273cf8f54e..2d2928e418623 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -723,7 +723,7 @@ Bug Fixes to C++ Support
 - Clang now ignores template parameters only used within the exception 
specification of candidate function
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
-- Fix a bug with checking constrained non-type template parameters for 
equivalence.
+- Fix a bug with checking constrained non-type template parameters for 
equivalence. Fixes (#GH77377).
 
 Bug Fixes to AST Handling
 ^

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


[clang] [Clang][Sema] ASTContext::getUnconstrainedType propagates dependence (PR #92425)

2024-05-16 Thread Krystian Stasiowski via cfe-commits


@@ -723,6 +723,7 @@ Bug Fixes to C++ Support
 - Clang now ignores template parameters only used within the exception 
specification of candidate function
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
+- Fix a bug with checking constrained non-type template parameters for 
equivalence.

sdkrystian wrote:

Good catch :)

https://github.com/llvm/llvm-project/pull/92425
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Reapply "[Clang][Sema] Earlier type checking for builtin unary operators (#90500)" (PR #92283)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@Caslyn [[expr.prim.this] p3](http://eel.is/c++draft/expr.prim.this#3) states:
> [...] the expression this is a prvalue of type “pointer to _cv-qualifier-seq_ 
> `X`” wherever `X` is the current class [...]

And [[over.match.oper] p1](http://eel.is/c++draft/over.match.oper#1) states:
> If no operand of an operator in an expression has a type that is a class or 
> an enumeration, the operator is assumed to be a built-in operator and 
> interpreted according to 
> [[expr.compound]](http://eel.is/c++draft/expr.compound).

Since the type of `this` is a pointer, `++this` uses the built-in prefix 
increment operator. The operand of the built-in prefix increment operator must 
be an lvalue (and `this` is a prvalue).

https://github.com/llvm/llvm-project/pull/92283
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] ASTContext::getUnconstrainedType propagates dependence (PR #92425)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92425

>From c26365ef78366b5c200d085ddc4211db1b2054e0 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 10:59:03 -0400
Subject: [PATCH] [Clang][Sema] ASTContext::getUnconstrainedType propagates
 dependence

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/AST/ASTContext.cpp  |  3 ++-
 .../temp/temp.decls/temp.fct/temp.func.order/p2.cpp   | 11 +++
 3 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 
clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index be4cded276321..21f273cf8f54e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -723,6 +723,7 @@ Bug Fixes to C++ Support
 - Clang now ignores template parameters only used within the exception 
specification of candidate function
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
+- Fix a bug with checking constrained non-type template parameters for 
equivalence.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 4475f399a120b..8fc2bb8c401c2 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5910,7 +5910,8 @@ QualType ASTContext::getUnconstrainedType(QualType T) 
const {
   if (auto *AT = CanonT->getAs()) {
 if (!AT->isConstrained())
   return T;
-return getQualifiedType(getAutoType(QualType(), AT->getKeyword(), false,
+return getQualifiedType(getAutoType(QualType(), AT->getKeyword(),
+AT->isDependentType(),
 AT->containsUnexpandedParameterPack()),
 T.getQualifiers());
   }
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp 
b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
new file mode 100644
index 0..ca753ec0c2d06
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// expected-no-diagnostics
+
+template
+concept C = sizeof(T) == sizeof(int);
+
+template
+struct A;
+
+template
+struct A;

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


[clang] [Clang][Sema] ASTContext::getUnconstrainedType propagates dependence (PR #92425)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/92425
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] ASTContext::getUnconstrainedType propagates dependence (PR #92425)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/92425

When the argument passed to `ASTContext::getUnconstrainedType` is an 
unconstrained `AutoType`, will return the argument unchanged. However, when 
called with a constrained `AutoType`, an unconstrained, non-dependent 
`AutoType` will be returned even if the argument was dependent. Consider the 
following:
```cpp
template
concept C = sizeof(T) == sizeof(int);

template
struct A;

template
struct A { }; // error: class template partial specialization is not more 
specialized than the primary template
```
When comparing the template parameters for equivalence, 
`ASTContext::getUnconstrainedType` is used to remove the constraints per 
[[temp.over.link] p6 sentence 
2](http://eel.is/c++draft/temp.over.link#6.sentence-2). For the template 
parameter `N` of the class template, it returns a dependent `AutoType`. For the 
template parameter `N` of the class template partial specialization, it returns 
a non-dependent `AutoType`. We subsequently compare the adjusted types and find 
they are not equivalent, thus we consider the partial specialization to not be 
more specialized than the primary template per [[temp.func.order] 
p6.2.2](http://eel.is/c++draft/temp.func.order#6.2.2). 

This patch changes `ASTContext::getUnconstrainedType` such that the dependence 
of a constrained `AutoType` will propagate to the returned unconstrained 
`AutoType`. This causes the above example to be correctly accepted, fixing 
#77377.

>From 7905c01b3501f211c044649052d7556b6cacd4a3 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 16 May 2024 10:59:03 -0400
Subject: [PATCH] [Clang][Sema] ASTContext::getUnconstrainedType propagates
 dependence

---
 clang/docs/ReleaseNotes.rst   |  1 +
 clang/lib/AST/ASTContext.cpp  |  3 ++-
 .../temp/temp.decls/temp.fct/temp.func.order/p2.cpp   | 11 +++
 3 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 
clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index be4cded276321..21f273cf8f54e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -723,6 +723,7 @@ Bug Fixes to C++ Support
 - Clang now ignores template parameters only used within the exception 
specification of candidate function
   templates during partial ordering when deducing template arguments from a 
function declaration or when
   taking the address of a function template.
+- Fix a bug with checking constrained non-type template parameters for 
equivalence.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 4475f399a120b..8fc2bb8c401c2 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5910,7 +5910,8 @@ QualType ASTContext::getUnconstrainedType(QualType T) 
const {
   if (auto *AT = CanonT->getAs()) {
 if (!AT->isConstrained())
   return T;
-return getQualifiedType(getAutoType(QualType(), AT->getKeyword(), false,
+return getQualifiedType(getAutoType(QualType(), AT->getKeyword(),
+AT->isDependentType(),
 AT->containsUnexpandedParameterPack()),
 T.getQualifiers());
   }
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp 
b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
new file mode 100644
index 0..5c908d789d511
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p2.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// expected-no-diagnostics
+
+template
+concept C = sizeof(T) == sizeof(int);
+
+template
+struct A;
+
+template
+struct A { };

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


[clang] [Clang] Properly set the value category of dependent unary operators (PR #88740)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@cor3ntin I believe this causes the crash reported in #92275

https://github.com/llvm/llvm-project/pull/88740
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

> Yeah, that seems incredibly reasonable and a much lower touch here with fewer 
> concerns about the side-effects that we got here.

Should I open a PR then?

https://github.com/llvm/llvm-project/pull/91842
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] visit constraint of NTTP (PR #91842)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

I don't think this is the right approach. I stepped though the example and the 
reason we reject is because:
- We substitute a dependent `AutoType` in for the types of the template 
parameters when they are initially built.
- We call `getMoreSpecialized` determine whether the partial specialization is 
more specialized than the primary.
- We determine that neither template is at least as specialized as the other 
via `isAtLeastAsSpecializedAs`.
- We call `TemplateParameterListsAreEqual` per [[temp.func.order] 
p6.2.2](http://eel.is/c++draft/temp.func.order#6.2.2) to check for template 
parameter equivalence, and compare the two template parameters by calling 
`MatchTemplateParameterKind`.
- `MatchTemplateParameterKind` calls `ASTContext::getUnconstrainedType` to get 
the unconstrained type of the template parameters per [[temp.over.link] p6 
sentence 2](http://eel.is/c++draft/temp.over.link#6.sentence-2). For class 
templates template parameter, it returns the type unchanged (a ***dependent*** 
`AutoType`). For the class template partial specializations template parameter, 
it returns an unconstrained `AutoType` ***that isn't dependent***. 
- We compare the adjusted types and determine they aren't equal, so we consider 
neither template to be more specialized than the other. 

So, I think the correct fix is to propagate dependence in 
`ASTContext::getUnconstrainedType`. I have a branch that implements this 
[here](https://github.com/sdkrystian/llvm-project/tree/partial-spec-dependent-auto).
 WDYT @erichkeane @cor3ntin?

https://github.com/llvm/llvm-project/pull/91842
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Don't build CXXDependentScopeMemberExprs for potentially implicit class member access expressions (PR #92318)

2024-05-16 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92318

>From 6c8646dbb04cc5898fe7f67c9923036b2f68b56d Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 15 May 2024 16:13:03 -0400
Subject: [PATCH 1/3] [Clang][Sema] Don't build CXXDependentScopeMemberExprs
 for potentially implicit class member access expressions

---
 clang/include/clang/Sema/Sema.h   | 11 +--
 clang/lib/Sema/SemaCXXScopeSpec.cpp   |  8 ++
 clang/lib/Sema/SemaExpr.cpp   | 31 ++
 clang/lib/Sema/SemaTemplate.cpp   | 98 ++-
 clang/lib/Sema/TreeTransform.h|  6 +-
 .../class.mfct/class.mfct.non-static/p3.cpp   | 91 -
 ...ms-function-specialization-class-scope.cpp | 52 ++
 .../ms-lookup-template-base-classes.cpp   | 12 +--
 .../ASTMatchers/ASTMatchersNodeTest.cpp   |  6 +-
 9 files changed, 206 insertions(+), 109 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6a414aa57f32b..779e3134b3067 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5366,11 +5366,9 @@ class Sema final : public SemaBase {
   bool UseArgumentDependentLookup(const CXXScopeSpec , const LookupResult 
,
   bool HasTrailingLParen);
 
-  ExprResult
-  BuildQualifiedDeclarationNameExpr(CXXScopeSpec ,
-const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S,
-TypeSourceInfo **RecoveryTSI = nullptr);
+  ExprResult BuildQualifiedDeclarationNameExpr(
+  CXXScopeSpec , const DeclarationNameInfo ,
+  bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
 
   ExprResult BuildDeclarationNameExpr(const CXXScopeSpec , LookupResult ,
   bool NeedsADL,
@@ -8982,7 +8980,8 @@ class Sema final : public SemaBase {
   ExprResult
   BuildQualifiedTemplateIdExpr(CXXScopeSpec , SourceLocation TemplateKWLoc,
const DeclarationNameInfo ,
-   const TemplateArgumentListInfo *TemplateArgs);
+   const TemplateArgumentListInfo *TemplateArgs,
+   bool IsAddressOfOperand);
 
   TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec ,
  SourceLocation TemplateKWLoc,
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index fca5bd131bbc0..c405fbc0aa421 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -796,6 +796,14 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, 
NestedNameSpecInfo ,
 Diag(IdInfo.IdentifierLoc,
  diag::ext_undeclared_unqual_id_with_dependent_base)
 << IdInfo.Identifier << ContainingClass;
+// Fake up a nested-name-specifier that starts with the
+// injected-class-name of the enclosing class.
+QualType T = Context.getTypeDeclType(ContainingClass);
+TypeLocBuilder TLB;
+TLB.pushTrivial(Context, T, IdInfo.IdentifierLoc);
+SS.Extend(Context, /*TemplateKWLoc=*/SourceLocation(),
+  TLB.getTypeLocInContext(Context, T), IdInfo.IdentifierLoc);
+// Add the identifier to form a dependent name.
 SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc,
   IdInfo.CCLoc);
 return false;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ec84798e4ce60..ad6cfb632fd94 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2946,26 +2946,14 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec ,
 /// this path.
 ExprResult Sema::BuildQualifiedDeclarationNameExpr(
 CXXScopeSpec , const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S, TypeSourceInfo **RecoveryTSI) {
-  if (NameInfo.getName().isDependentName())
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  DeclContext *DC = computeDeclContext(SS, false);
-  if (!DC)
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  if (RequireCompleteDeclContext(SS, DC))
-return ExprError();
-
+bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI) {
   LookupResult R(*this, NameInfo, LookupOrdinaryName);
-  LookupQualifiedName(R, DC);
+  LookupParsedName(R, /*S=*/nullptr, , /*ObjectType=*/QualType());
 
   if (R.isAmbiguous())
 return ExprError();
 
-  if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)
+  if (R.wasNotFoundInCurrentInstantiation() || SS.isInvalid())
 return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
   

[clang] Reapply "[Clang][Sema] Earlier type checking for builtin unary operators (#90500)" (PR #92283)

2024-05-15 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/92283
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)

2024-05-15 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/91534
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Don't build CXXDependentScopeMemberExprs for potentially implicit class member access expressions (PR #92318)

2024-05-15 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92318

>From a5ed54f967e4a15a80f41ee648f79e77202906d8 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 15 May 2024 16:13:03 -0400
Subject: [PATCH 1/2] [Clang][Sema] Don't build CXXDependentScopeMemberExprs
 for potentially implicit class member access expressions

---
 clang/include/clang/Sema/Sema.h   | 11 +--
 clang/lib/Sema/SemaCXXScopeSpec.cpp   |  8 ++
 clang/lib/Sema/SemaExpr.cpp   | 31 ++
 clang/lib/Sema/SemaTemplate.cpp   | 98 ++-
 clang/lib/Sema/TreeTransform.h|  6 +-
 .../class.mfct/class.mfct.non-static/p3.cpp   | 91 -
 ...ms-function-specialization-class-scope.cpp | 52 ++
 .../ms-lookup-template-base-classes.cpp   | 12 +--
 .../ASTMatchers/ASTMatchersNodeTest.cpp   |  6 +-
 9 files changed, 206 insertions(+), 109 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6a414aa57f32b..779e3134b3067 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5366,11 +5366,9 @@ class Sema final : public SemaBase {
   bool UseArgumentDependentLookup(const CXXScopeSpec , const LookupResult 
,
   bool HasTrailingLParen);
 
-  ExprResult
-  BuildQualifiedDeclarationNameExpr(CXXScopeSpec ,
-const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S,
-TypeSourceInfo **RecoveryTSI = nullptr);
+  ExprResult BuildQualifiedDeclarationNameExpr(
+  CXXScopeSpec , const DeclarationNameInfo ,
+  bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
 
   ExprResult BuildDeclarationNameExpr(const CXXScopeSpec , LookupResult ,
   bool NeedsADL,
@@ -8982,7 +8980,8 @@ class Sema final : public SemaBase {
   ExprResult
   BuildQualifiedTemplateIdExpr(CXXScopeSpec , SourceLocation TemplateKWLoc,
const DeclarationNameInfo ,
-   const TemplateArgumentListInfo *TemplateArgs);
+   const TemplateArgumentListInfo *TemplateArgs,
+   bool IsAddressOfOperand);
 
   TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec ,
  SourceLocation TemplateKWLoc,
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index fca5bd131bbc0..c405fbc0aa421 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -796,6 +796,14 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, 
NestedNameSpecInfo ,
 Diag(IdInfo.IdentifierLoc,
  diag::ext_undeclared_unqual_id_with_dependent_base)
 << IdInfo.Identifier << ContainingClass;
+// Fake up a nested-name-specifier that starts with the
+// injected-class-name of the enclosing class.
+QualType T = Context.getTypeDeclType(ContainingClass);
+TypeLocBuilder TLB;
+TLB.pushTrivial(Context, T, IdInfo.IdentifierLoc);
+SS.Extend(Context, /*TemplateKWLoc=*/SourceLocation(),
+  TLB.getTypeLocInContext(Context, T), IdInfo.IdentifierLoc);
+// Add the identifier to form a dependent name.
 SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc,
   IdInfo.CCLoc);
 return false;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ec84798e4ce60..ad6cfb632fd94 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2946,26 +2946,14 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec ,
 /// this path.
 ExprResult Sema::BuildQualifiedDeclarationNameExpr(
 CXXScopeSpec , const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S, TypeSourceInfo **RecoveryTSI) {
-  if (NameInfo.getName().isDependentName())
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  DeclContext *DC = computeDeclContext(SS, false);
-  if (!DC)
-return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
- NameInfo, /*TemplateArgs=*/nullptr);
-
-  if (RequireCompleteDeclContext(SS, DC))
-return ExprError();
-
+bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI) {
   LookupResult R(*this, NameInfo, LookupOrdinaryName);
-  LookupQualifiedName(R, DC);
+  LookupParsedName(R, /*S=*/nullptr, , /*ObjectType=*/QualType());
 
   if (R.isAmbiguous())
 return ExprError();
 
-  if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)
+  if (R.wasNotFoundInCurrentInstantiation() || SS.isInvalid())
 return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
   

[clang] [Clang][Sema] Don't build CXXDependentScopeMemberExprs for potentially implicit class member access expressions (PR #92318)

2024-05-15 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/92318

According to [[expr.prim.id.general] 
p2](http://eel.is/c++draft/expr.prim.id.general#2):
> If an _id-expression_ `E` denotes a non-static non-type member of some class 
> `C` at a point where the current class is `X` and
> - `E` is potentially evaluated or `C` is `X` or a base class of `X`, and
> - `E` is not the _id-expression_ of a class member access expression, and
> - if `E` is a _qualified-id_, `E` is not the un-parenthesized operand of the 
> unary `&` operator,
>
> the _id-expression_ is transformed into a class member access expression 
> using `(*this)` as the object expression.

Consider the following:
```cpp
struct A
{
void f0();

template
void f1();
};

template
struct B : T
{
auto g0() -> decltype(T::f0()); // ok

auto g1() -> decltype(T::template f1()); // error: call to non-static 
member function without an object argument
};

template struct B;
```

Clang incorrectly rejects the call to `f1` in the _trailing-return-type_ of 
`g1`. Furthermore, the following snippet results in a crash during codegen:
```cpp
struct A
{
void f();
};

template
struct B : T
{
template
static void g();

template<>
void g()
{
return T::f(); // crash here
}
};

template struct B;
```
This happens because we unconditionally build a `CXXDependentScopeMemberExpr` 
(with an implicit object expression) for `T::f` when parsing the template 
definition, even though we don't know whether `g` is an implicit object member 
function yet.

This patch fixes these issues by instead building `DependentScopeDeclRefExpr`s 
for such expressions, and only transforming them into implicit class member 
access expressions during instantiation. Since we implemented the MS 
"unqualified lookup into dependent bases" extension by building an implicit 
class member access (and relying on the first component name of the 
_nested-name-specifier_ to be looked up in the context of the object expression 
during instantiation), we instead pre-append a fake _nested-name-specifier_ 
that refers to the injected-class-name of the enclosing class. This patch also 
refactors `Sema::BuildQualifiedDeclarationNameExpr` and 
`Sema::BuildQualifiedTemplateIdExpr`, streamlining their implementation and 
removing any redundant checks.

>From a5ed54f967e4a15a80f41ee648f79e77202906d8 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 15 May 2024 16:13:03 -0400
Subject: [PATCH] [Clang][Sema] Don't build CXXDependentScopeMemberExprs for
 potentially implicit class member access expressions

---
 clang/include/clang/Sema/Sema.h   | 11 +--
 clang/lib/Sema/SemaCXXScopeSpec.cpp   |  8 ++
 clang/lib/Sema/SemaExpr.cpp   | 31 ++
 clang/lib/Sema/SemaTemplate.cpp   | 98 ++-
 clang/lib/Sema/TreeTransform.h|  6 +-
 .../class.mfct/class.mfct.non-static/p3.cpp   | 91 -
 ...ms-function-specialization-class-scope.cpp | 52 ++
 .../ms-lookup-template-base-classes.cpp   | 12 +--
 .../ASTMatchers/ASTMatchersNodeTest.cpp   |  6 +-
 9 files changed, 206 insertions(+), 109 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6a414aa57f32b..779e3134b3067 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5366,11 +5366,9 @@ class Sema final : public SemaBase {
   bool UseArgumentDependentLookup(const CXXScopeSpec , const LookupResult 
,
   bool HasTrailingLParen);
 
-  ExprResult
-  BuildQualifiedDeclarationNameExpr(CXXScopeSpec ,
-const DeclarationNameInfo ,
-bool IsAddressOfOperand, const Scope *S,
-TypeSourceInfo **RecoveryTSI = nullptr);
+  ExprResult BuildQualifiedDeclarationNameExpr(
+  CXXScopeSpec , const DeclarationNameInfo ,
+  bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
 
   ExprResult BuildDeclarationNameExpr(const CXXScopeSpec , LookupResult ,
   bool NeedsADL,
@@ -8982,7 +8980,8 @@ class Sema final : public SemaBase {
   ExprResult
   BuildQualifiedTemplateIdExpr(CXXScopeSpec , SourceLocation TemplateKWLoc,
const DeclarationNameInfo ,
-   const TemplateArgumentListInfo *TemplateArgs);
+   const TemplateArgumentListInfo *TemplateArgs,
+   bool IsAddressOfOperand);
 
   TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec ,
  SourceLocation TemplateKWLoc,
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp 
b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index fca5bd131bbc0..c405fbc0aa421 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp

[clang] Reapply "[Clang][Sema] Earlier type checking for builtin unary operators (#90500)" (PR #92283)

2024-05-15 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

All the new changes are in 5ce0e969f3f94e9694545fe71b14fd8eb086f33e

https://github.com/llvm/llvm-project/pull/92283
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)

2024-05-15 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/91534

>From 34af5511804b8c0fd8b0d742653f6017dd8e9e87 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 8 May 2024 08:43:23 -0400
Subject: [PATCH 1/2] [Clang][Sema] Do not mark template parameters in the
 exception specification as used during partial ordering

---
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 36 +++---
 .../temp.deduct/temp.deduct.partial/p3.cpp| 72 +++
 2 files changed, 100 insertions(+), 8 deletions(-)
 create mode 100644 
clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp

diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 853c0e1b50619..b5d405111fe4c 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5453,7 +5453,7 @@ static bool isAtLeastAsSpecializedAs(Sema , 
SourceLocation Loc,
 // is used.
 if (DeduceTemplateArgumentsByTypeMatch(
 S, TemplateParams, FD2->getType(), FD1->getType(), Info, Deduced,
-TDF_None,
+TDF_AllowCompatibleFunctionType,
 /*PartialOrdering=*/true) != TemplateDeductionResult::Success)
   return false;
 break;
@@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , 
SourceLocation Loc,
   switch (TPOC) {
   case TPOC_Call:
 for (unsigned I = 0, N = Args2.size(); I != N; ++I)
-  ::MarkUsedTemplateParameters(S.Context, Args2[I], false,
-   TemplateParams->getDepth(),
-   UsedParameters);
+  ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false,
+   TemplateParams->getDepth(), UsedParameters);
 break;
 
   case TPOC_Conversion:
-::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false,
+::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(),
+ /*OnlyDeduced=*/false,
  TemplateParams->getDepth(), UsedParameters);
 break;
 
   case TPOC_Other:
-::MarkUsedTemplateParameters(S.Context, FD2->getType(), false,
- TemplateParams->getDepth(),
- UsedParameters);
+// We do not deduce template arguments from the exception specification
+// when determining the primary template of a function template
+// specialization or when taking the address of a function template.
+// Therefore, we do not mark template parameters in the exception
+// specification as used during partial ordering to prevent the following
+// from being ambiguous:
+//
+//   template
+//   void f(U) noexcept(noexcept(T())); // #1
+//
+//   template
+//   void f(T*) noexcept; // #2
+//
+//   template<>
+//   void f(int*) noexcept; // explicit specialization of #2
+//
+// Although there is no corresponding wording in the standard, this seems
+// to be the intended behavior given the definition of
+// 'deduction substitution loci' in [temp.deduct].
+::MarkUsedTemplateParameters(
+S.Context,
+S.Context.getFunctionTypeWithExceptionSpec(FD2->getType(), EST_None),
+/*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters);
 break;
   }
 
diff --git 
a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp 
b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp
new file mode 100644
index 0..cc1d4ecda2ecc
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+template
+struct A { };
+
+constexpr A a;
+constexpr A b;
+
+constexpr int* x = nullptr;
+constexpr short* y = nullptr;
+
+namespace ExplicitArgs {
+  template
+  constexpr int f(U) noexcept(noexcept(T())) {
+return 0;
+  }
+
+  template
+  constexpr int f(T*) noexcept {
+return 1;
+  }
+
+  template<>
+  constexpr int f(int*) noexcept {
+return 2;
+  }
+
+  static_assert(f(1) == 0);
+  static_assert(f(y) == 1);
+  static_assert(f(x) == 2);
+
+  template
+  constexpr int g(U*) noexcept(noexcept(T())) {
+return 3;
+  }
+
+  template
+  constexpr int g(T) noexcept {
+return 4;
+  }
+
+  template<>
+  constexpr int g(int*) noexcept {
+return 5;
+  }
+
+  static_assert(g(y) == 3);
+  static_assert(g(1) == 4);
+  static_assert(g(x) == 5);
+} // namespace ExplicitArgs
+
+namespace DeducedArgs {
+  template
+  constexpr int f(T, A) noexcept(B) {
+return 0;
+  }
+
+  template
+  constexpr int f(T*, A) noexcept(B && B) {
+return 1;
+  }
+
+  template<>
+  constexpr int f(int*, A) {
+return 2;
+  }
+
+  static_assert(f(x, a) == 0);
+  static_assert(f(y, a) == 1);
+  static_assert(f(x, a) == 2);
+} // namespace DeducedArgs

>From 

[clang] Reapply "[Clang][Sema] Earlier type checking for builtin unary operators (#90500)" (PR #92283)

2024-05-15 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/92283

This patch reapplies #90500, addressing a bug which caused binary operators 
with dependent operands to be incorrectly rebuilt by `TreeTransform`. 

>From 365d97508883eb5a4f9b898f8277d16e1f6d3862 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Tue, 14 May 2024 13:23:45 -0400
Subject: [PATCH 1/2] Reapply "[Clang][Sema] Earlier type checking for builtin
 unary operators (#90500)"

---
 clang/docs/ReleaseNotes.rst   |   3 +
 clang/include/clang/AST/Type.h|   5 +-
 clang/lib/Sema/SemaExpr.cpp   | 351 +-
 clang/test/AST/ast-dump-expr-json.cpp |   4 +-
 clang/test/AST/ast-dump-expr.cpp  |   2 +-
 clang/test/AST/ast-dump-lambda.cpp|   2 +-
 .../expr/expr.unary/expr.unary.general/p1.cpp |  65 
 clang/test/CXX/over/over.built/ast.cpp| 158 ++--
 clang/test/CXX/over/over.built/p10.cpp|   2 +-
 clang/test/CXX/over/over.built/p11.cpp|   2 +-
 .../temp.res/temp.dep/temp.dep.type/p4.cpp|  25 +-
 clang/test/Frontend/noderef_templates.cpp |   4 +-
 clang/test/SemaCXX/cxx2b-deducing-this.cpp|   6 +-
 .../test/SemaTemplate/class-template-spec.cpp |  12 +-
 .../ASTMatchers/ASTMatchersNarrowingTest.cpp  |   6 +-
 15 files changed, 402 insertions(+), 245 deletions(-)
 create mode 100644 clang/test/CXX/expr/expr.unary/expr.unary.general/p1.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 49ab222bec405..a2e44efe41347 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -55,6 +55,9 @@ C++ Specific Potentially Breaking Changes
 
 - Clang now rejects pointer to member from parenthesized expression in 
unevaluated context such as ``decltype(&(foo::bar))``. (#GH40906).
 
+- Clang now performs semantic analysis for unary operators with dependent 
operands
+  that are known to be of non-class non-enumeration type prior to 
instantiation.
+
 ABI Changes in This Version
 ---
 - Fixed Microsoft name mangling of implicitly defined variables used for thread
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index e6643469e0b33..da3834f19ca04 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -8044,7 +8044,10 @@ inline bool Type::isUndeducedType() const {
 /// Determines whether this is a type for which one can define
 /// an overloaded operator.
 inline bool Type::isOverloadableType() const {
-  return isDependentType() || isRecordType() || isEnumeralType();
+  if (!CanonicalType->isDependentType())
+return isRecordType() || isEnumeralType();
+  return !isArrayType() && !isFunctionType() && !isAnyPointerType() &&
+ !isMemberPointerType();
 }
 
 /// Determines whether this type is written as a typedef-name.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ec84798e4ce60..18fd5ba700ad3 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -672,12 +672,12 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
 
   // We don't want to throw lvalue-to-rvalue casts on top of
   // expressions of certain types in C++.
-  if (getLangOpts().CPlusPlus &&
-  (E->getType() == Context.OverloadTy ||
-   // FIXME: This is a hack! We want the lvalue-to-rvalue conversion 
applied
-   // to pointer types even if the pointee type is dependent.
-   (T->isDependentType() && !T->isPointerType()) || T->isRecordType()))
-return E;
+  if (getLangOpts().CPlusPlus) {
+if (T == Context.OverloadTy || T->isRecordType() ||
+(T->isDependentType() && !T->isAnyPointerType() &&
+ !T->isMemberPointerType()))
+  return E;
+  }
 
   // The C standard is actually really unclear on this point, and
   // DR106 tells us what the result should be but not why.  It's
@@ -10827,7 +10827,7 @@ static bool checkArithmeticIncompletePointerType(Sema 
, SourceLocation Loc,
   if (const AtomicType *ResAtomicType = ResType->getAs())
 ResType = ResAtomicType->getValueType();
 
-  assert(ResType->isAnyPointerType() && !ResType->isDependentType());
+  assert(ResType->isAnyPointerType());
   QualType PointeeTy = ResType->getPointeeType();
   return S.RequireCompleteSizedType(
   Loc, PointeeTy,
@@ -13957,9 +13957,6 @@ static QualType CheckIncrementDecrementOperand(Sema , 
Expr *Op,
ExprObjectKind ,
SourceLocation OpLoc, bool 
IsInc,
bool IsPrefix) {
-  if (Op->isTypeDependent())
-return S.Context.DependentTy;
-
   QualType ResType = Op->getType();
   // Atomic types can be used for increment / decrement where the non-atomic
   // versions can, so ignore the _Atomic() specifier for the purpose of
@@ -14410,9 +14407,6 @@ static void RecordModifiableNonNullParam(Sema , 

[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)

2024-05-15 Thread Krystian Stasiowski via cfe-commits


@@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , 
SourceLocation Loc,
   switch (TPOC) {
   case TPOC_Call:
 for (unsigned I = 0, N = Args2.size(); I != N; ++I)
-  ::MarkUsedTemplateParameters(S.Context, Args2[I], false,
-   TemplateParams->getDepth(),
-   UsedParameters);
+  ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false,
+   TemplateParams->getDepth(), UsedParameters);
 break;
 
   case TPOC_Conversion:
-::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false,
+::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(),
+ /*OnlyDeduced=*/false,
  TemplateParams->getDepth(), UsedParameters);
 break;
 
   case TPOC_Other:
-::MarkUsedTemplateParameters(S.Context, FD2->getType(), false,
- TemplateParams->getDepth(),
- UsedParameters);
+// We do not deduce template arguments from the exception specification
+// when determining the primary template of a function template
+// specialization or when taking the address of a function template.
+// Therefore, we do not mark template parameters in the exception
+// specification as used during partial ordering to prevent the following
+// from being ambiguous:
+//
+//   template
+//   void f(U) noexcept(noexcept(T())); // #1
+//
+//   template
+//   void f(T*) noexcept; // #2
+//
+//   template<>
+//   void f(int*) noexcept; // explicit specialization of #2
+//
+// Although there is no corresponding wording in the standard, this seems

sdkrystian wrote:

I've seen it take anywhere from a day to a month. I'll be sure to update this 
once the issue is opened!

https://github.com/llvm/llvm-project/pull/91534
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)

2024-05-15 Thread Krystian Stasiowski via cfe-commits


@@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , 
SourceLocation Loc,
   switch (TPOC) {
   case TPOC_Call:
 for (unsigned I = 0, N = Args2.size(); I != N; ++I)
-  ::MarkUsedTemplateParameters(S.Context, Args2[I], false,
-   TemplateParams->getDepth(),
-   UsedParameters);
+  ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false,
+   TemplateParams->getDepth(), UsedParameters);
 break;
 
   case TPOC_Conversion:
-::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false,
+::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(),
+ /*OnlyDeduced=*/false,
  TemplateParams->getDepth(), UsedParameters);
 break;
 
   case TPOC_Other:
-::MarkUsedTemplateParameters(S.Context, FD2->getType(), false,
- TemplateParams->getDepth(),
- UsedParameters);
+// We do not deduce template arguments from the exception specification
+// when determining the primary template of a function template
+// specialization or when taking the address of a function template.
+// Therefore, we do not mark template parameters in the exception
+// specification as used during partial ordering to prevent the following
+// from being ambiguous:
+//
+//   template
+//   void f(U) noexcept(noexcept(T())); // #1
+//
+//   template
+//   void f(T*) noexcept; // #2
+//
+//   template<>
+//   void f(int*) noexcept; // explicit specialization of #2
+//
+// Although there is no corresponding wording in the standard, this seems

sdkrystian wrote:

@erichkeane Filed an issue [here](https://github.com/cplusplus/CWG/issues/537). 
It might be a little while before an actual core issue is opened, so would it 
be alright to merge this before that happens?

https://github.com/llvm/llvm-project/pull/91534
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] Reapply "[Clang] Unify interface for accessing template arguments as written for class/variable template specializations (#81642)" (PR #91393)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/91393
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Earlier type checking for builtin unary operators (PR #90500)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

The issue seems to be that `TreeTransform::RebuildCXXOperatorCallExpr` relies 
on `isOverloadableType` to always be true for dependent types

https://github.com/llvm/llvm-project/pull/90500
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Earlier type checking for builtin unary operators (PR #90500)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

Well this took forever to reduce:
```cpp
template
struct A;

template
bool operator==(const A&, const A&);

template
void f(int *x)
{
[&](auto *y) { return x == y; };
}

void g()
{
f(nullptr);
}
```
We initially build a `CXXOperatorCallExpr` during parsing for the comparison, 
but `TreeTransform` prematurely rebuilds it as a builtin binary operator when 
`f` is instantiated.

https://github.com/llvm/llvm-project/pull/90500
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Earlier type checking for builtin unary operators (PR #90500)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

Reverted in #92149

https://github.com/llvm/llvm-project/pull/90500
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Revert "[Clang][Sema] Earlier type checking for builtin unary operators (#90500)" (PR #92149)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/92149
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Revert "[Clang][Sema] Earlier type checking for builtin unary operators (#90500)" (PR #92149)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/92149

>From 55a5910281b9f6e150adc29b3a1b9c149ca0ef55 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Tue, 14 May 2024 13:17:29 -0400
Subject: [PATCH] Revert "[Clang][Sema] Earlier type checking for builtin unary
 operators (#90500)"

This reverts commit 8019cc94658d133583f7be6cd0023d30b0f3.
---
 clang/docs/ReleaseNotes.rst   |   3 -
 clang/include/clang/AST/Type.h|   5 +-
 clang/lib/Sema/SemaExpr.cpp   | 351 +-
 clang/test/AST/ast-dump-expr-json.cpp |   4 +-
 clang/test/AST/ast-dump-expr.cpp  |   2 +-
 clang/test/AST/ast-dump-lambda.cpp|   2 +-
 .../expr/expr.unary/expr.unary.general/p1.cpp |  65 
 clang/test/CXX/over/over.built/ast.cpp| 158 ++--
 clang/test/CXX/over/over.built/p10.cpp|   2 +-
 clang/test/CXX/over/over.built/p11.cpp|   2 +-
 .../temp.res/temp.dep/temp.dep.type/p4.cpp|  25 +-
 clang/test/Frontend/noderef_templates.cpp |   4 +-
 clang/test/SemaCXX/cxx2b-deducing-this.cpp|   6 +-
 .../test/SemaTemplate/class-template-spec.cpp |  12 +-
 .../ASTMatchers/ASTMatchersNarrowingTest.cpp  |   6 +-
 15 files changed, 245 insertions(+), 402 deletions(-)
 delete mode 100644 clang/test/CXX/expr/expr.unary/expr.unary.general/p1.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a2e44efe41347..49ab222bec405 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -55,9 +55,6 @@ C++ Specific Potentially Breaking Changes
 
 - Clang now rejects pointer to member from parenthesized expression in 
unevaluated context such as ``decltype(&(foo::bar))``. (#GH40906).
 
-- Clang now performs semantic analysis for unary operators with dependent 
operands
-  that are known to be of non-class non-enumeration type prior to 
instantiation.
-
 ABI Changes in This Version
 ---
 - Fixed Microsoft name mangling of implicitly defined variables used for thread
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index da3834f19ca04..e6643469e0b33 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -8044,10 +8044,7 @@ inline bool Type::isUndeducedType() const {
 /// Determines whether this is a type for which one can define
 /// an overloaded operator.
 inline bool Type::isOverloadableType() const {
-  if (!CanonicalType->isDependentType())
-return isRecordType() || isEnumeralType();
-  return !isArrayType() && !isFunctionType() && !isAnyPointerType() &&
- !isMemberPointerType();
+  return isDependentType() || isRecordType() || isEnumeralType();
 }
 
 /// Determines whether this type is written as a typedef-name.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 18fd5ba700ad3..ec84798e4ce60 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -672,12 +672,12 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
 
   // We don't want to throw lvalue-to-rvalue casts on top of
   // expressions of certain types in C++.
-  if (getLangOpts().CPlusPlus) {
-if (T == Context.OverloadTy || T->isRecordType() ||
-(T->isDependentType() && !T->isAnyPointerType() &&
- !T->isMemberPointerType()))
-  return E;
-  }
+  if (getLangOpts().CPlusPlus &&
+  (E->getType() == Context.OverloadTy ||
+   // FIXME: This is a hack! We want the lvalue-to-rvalue conversion 
applied
+   // to pointer types even if the pointee type is dependent.
+   (T->isDependentType() && !T->isPointerType()) || T->isRecordType()))
+return E;
 
   // The C standard is actually really unclear on this point, and
   // DR106 tells us what the result should be but not why.  It's
@@ -10827,7 +10827,7 @@ static bool checkArithmeticIncompletePointerType(Sema 
, SourceLocation Loc,
   if (const AtomicType *ResAtomicType = ResType->getAs())
 ResType = ResAtomicType->getValueType();
 
-  assert(ResType->isAnyPointerType());
+  assert(ResType->isAnyPointerType() && !ResType->isDependentType());
   QualType PointeeTy = ResType->getPointeeType();
   return S.RequireCompleteSizedType(
   Loc, PointeeTy,
@@ -13957,6 +13957,9 @@ static QualType CheckIncrementDecrementOperand(Sema , 
Expr *Op,
ExprObjectKind ,
SourceLocation OpLoc, bool 
IsInc,
bool IsPrefix) {
+  if (Op->isTypeDependent())
+return S.Context.DependentTy;
+
   QualType ResType = Op->getType();
   // Atomic types can be used for increment / decrement where the non-atomic
   // versions can, so ignore the _Atomic() specifier for the purpose of
@@ -14407,6 +14410,9 @@ static void RecordModifiableNonNullParam(Sema , const 
Expr *Exp) {
 static QualType CheckIndirectionOperand(Sema , Expr *Op, ExprValueKind 

[clang] Revert "[Clang][Sema] Earlier type checking for builtin unary operators (#90500)" (PR #92149)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/92149

This reverts commit 8019cc94658d133583f7be6cd0023d30b0f3.

>From a55eb47a72fd6b5d703e7c20e2cbf5b2aa7fd78d Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Tue, 14 May 2024 13:17:29 -0400
Subject: [PATCH] Revert "[Clang][Sema] Earlier type checking for builtin unary
 operators (#90500)"

This reverts commit 8019cc94658d133583f7be6cd0023d30b0f3.
---
 clang/docs/ReleaseNotes.rst   |   3 -
 clang/include/clang/AST/Type.h|   5 +-
 clang/lib/Sema/SemaExpr.cpp   | 354 +-
 clang/test/AST/ast-dump-expr-json.cpp |   4 +-
 clang/test/AST/ast-dump-expr.cpp  |   2 +-
 clang/test/AST/ast-dump-lambda.cpp|   2 +-
 .../expr/expr.unary/expr.unary.general/p1.cpp |  65 
 clang/test/CXX/over/over.built/ast.cpp| 158 ++--
 clang/test/CXX/over/over.built/p10.cpp|   2 +-
 clang/test/CXX/over/over.built/p11.cpp|   2 +-
 .../temp.res/temp.dep/temp.dep.type/p4.cpp|  25 +-
 clang/test/Frontend/noderef_templates.cpp |   4 +-
 clang/test/SemaCXX/cxx2b-deducing-this.cpp|   6 +-
 .../test/SemaTemplate/class-template-spec.cpp |  12 +-
 .../ASTMatchers/ASTMatchersNarrowingTest.cpp  |   6 +-
 15 files changed, 246 insertions(+), 404 deletions(-)
 delete mode 100644 clang/test/CXX/expr/expr.unary/expr.unary.general/p1.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a2e44efe41347..49ab222bec405 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -55,9 +55,6 @@ C++ Specific Potentially Breaking Changes
 
 - Clang now rejects pointer to member from parenthesized expression in 
unevaluated context such as ``decltype(&(foo::bar))``. (#GH40906).
 
-- Clang now performs semantic analysis for unary operators with dependent 
operands
-  that are known to be of non-class non-enumeration type prior to 
instantiation.
-
 ABI Changes in This Version
 ---
 - Fixed Microsoft name mangling of implicitly defined variables used for thread
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index da3834f19ca04..e6643469e0b33 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -8044,10 +8044,7 @@ inline bool Type::isUndeducedType() const {
 /// Determines whether this is a type for which one can define
 /// an overloaded operator.
 inline bool Type::isOverloadableType() const {
-  if (!CanonicalType->isDependentType())
-return isRecordType() || isEnumeralType();
-  return !isArrayType() && !isFunctionType() && !isAnyPointerType() &&
- !isMemberPointerType();
+  return isDependentType() || isRecordType() || isEnumeralType();
 }
 
 /// Determines whether this type is written as a typedef-name.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 18fd5ba700ad3..e6c3fa51d54da 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -672,12 +672,12 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
 
   // We don't want to throw lvalue-to-rvalue casts on top of
   // expressions of certain types in C++.
-  if (getLangOpts().CPlusPlus) {
-if (T == Context.OverloadTy || T->isRecordType() ||
-(T->isDependentType() && !T->isAnyPointerType() &&
- !T->isMemberPointerType()))
-  return E;
-  }
+  if (getLangOpts().CPlusPlus &&
+  (E->getType() == Context.OverloadTy ||
+   // FIXME: This is a hack! We want the lvalue-to-rvalue conversion 
applied
+   // to pointer types even if the pointee type is dependent.
+   (T->isDependentType() && !T->isPointerType()) || T->isRecordType()))
+return E;
 
   // The C standard is actually really unclear on this point, and
   // DR106 tells us what the result should be but not why.  It's
@@ -10827,7 +10827,7 @@ static bool checkArithmeticIncompletePointerType(Sema 
, SourceLocation Loc,
   if (const AtomicType *ResAtomicType = ResType->getAs())
 ResType = ResAtomicType->getValueType();
 
-  assert(ResType->isAnyPointerType());
+  assert(ResType->isAnyPointerType() && !ResType->isDependentType());
   QualType PointeeTy = ResType->getPointeeType();
   return S.RequireCompleteSizedType(
   Loc, PointeeTy,
@@ -13955,8 +13955,11 @@ static QualType CheckCommaOperands(Sema , ExprResult 
, ExprResult ,
 static QualType CheckIncrementDecrementOperand(Sema , Expr *Op,
ExprValueKind ,
ExprObjectKind ,
-   SourceLocation OpLoc, bool 
IsInc,
-   bool IsPrefix) {
+   SourceLocation OpLoc,
+   bool IsInc, bool IsPrefix) {
+  if (Op->isTypeDependent())
+return S.Context.DependentTy;
+
   

[clang] [Clang][Sema] Earlier type checking for builtin unary operators (PR #90500)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

This seems to [break 
something](https://lab.llvm.org/buildbot/#/builders/121/builds/41631) in 
LLVM... investigating

https://github.com/llvm/llvm-project/pull/90500
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Earlier type checking for builtin unary operators (PR #90500)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/90500
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Earlier type checking for builtin unary operators (PR #90500)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@erichkeane Since I addressed @shafik's comments, it this good to be merged?

https://github.com/llvm/llvm-project/pull/90500
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Add tests for CWG issues regarding completeness of types (PR #92113)

2024-05-14 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/92113
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] Reapply "[Clang][Sema] Diagnose class member access expressions naming non-existent members of the current instantiation prior to instantiation in the absence of dependent

2024-05-13 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@eaeltsin @ilya-biryukov Fixed in 596a9c1f9b3179b3c77cbde1e96619292ce2a10a

https://github.com/llvm/llvm-project/pull/90152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix bug where operator-> typo corrects in the current instantiation (PR #91972)

2024-05-13 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/91972
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix bug where operator-> typo corrects in the current instantiation (PR #91972)

2024-05-13 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/91972

>From a013806c0199e260c37bc6b16b600e61e4caa1c9 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Mon, 13 May 2024 10:22:04 -0400
Subject: [PATCH 1/2] [Clang][Sema] Fix bug where operator-> typo corrects in
 the current instantiation

---
 clang/lib/Sema/SemaExprMember.cpp  | 10 +-
 .../CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp|  7 +++
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaExprMember.cpp 
b/clang/lib/Sema/SemaExprMember.cpp
index 9fa69da4f9685..ac81d4fd57654 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -995,8 +995,6 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
   // arrow operator was used with a dependent non-pointer object expression,
   // build a CXXDependentScopeMemberExpr.
   if (R.wasNotFoundInCurrentInstantiation() ||
-  (IsArrow && !BaseExprType->isPointerType() &&
-   BaseExprType->isDependentType()) ||
   (R.getLookupName().getCXXOverloadedOperator() == OO_Equal &&
(SS.isSet() ? SS.getScopeRep()->isDependent()
: BaseExprType->isDependentType(
@@ -1322,7 +1320,11 @@ static ExprResult LookupMemberExpr(Sema , LookupResult 
,
 else if (const ObjCObjectPointerType *Ptr =
  BaseType->getAs())
   BaseType = Ptr->getPointeeType();
-else if (!BaseType->isDependentType()) {
+else if (BaseType->isFunctionType())
+  goto fail;
+else if (BaseType->isDependentType())
+  BaseType = S.Context.DependentTy;
+else {
   if (BaseType->isRecordType()) {
 // Recover from arrow accesses to records, e.g.:
 //   struct MyRecord foo;
@@ -1337,8 +1339,6 @@ static ExprResult LookupMemberExpr(Sema , LookupResult 
,
   << FixItHint::CreateReplacement(OpLoc, ".");
 }
 IsArrow = false;
-  } else if (BaseType->isFunctionType()) {
-goto fail;
   } else {
 S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
 << BaseType << BaseExpr.get()->getSourceRange();
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp 
b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
index 1adbc33a701c1..fafd54bde7622 100644
--- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
@@ -551,4 +551,11 @@ namespace N4 {
 
   template void D::instantiated(D); // expected-note {{in instantiation of}}
 
+  template
+  struct Typo {
+void not_instantiated(Typo a) {
+  a->Not_instantiated;
+  a->typo;
+}
+  };
 } // namespace N4

>From f13826746be9893a48485275ef819b5cd454a53d Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Mon, 13 May 2024 11:57:47 -0400
Subject: [PATCH 2/2] [FOLD] fix operator-> with nested-name-specifier

---
 clang/lib/Sema/SemaExprMember.cpp | 41 ++-
 .../temp.res/temp.dep/temp.dep.type/p4.cpp| 20 +
 2 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/clang/lib/Sema/SemaExprMember.cpp 
b/clang/lib/Sema/SemaExprMember.cpp
index ac81d4fd57654..244488a0b562b 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1324,26 +1324,24 @@ static ExprResult LookupMemberExpr(Sema , 
LookupResult ,
   goto fail;
 else if (BaseType->isDependentType())
   BaseType = S.Context.DependentTy;
-else {
-  if (BaseType->isRecordType()) {
-// Recover from arrow accesses to records, e.g.:
-//   struct MyRecord foo;
-//   foo->bar
-// This is actually well-formed in C++ if MyRecord has an
-// overloaded operator->, but that should have been dealt with
-// by now--or a diagnostic message already issued if a problem
-// was encountered while looking for the overloaded operator->.
-if (!S.getLangOpts().CPlusPlus) {
-  S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
-  << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
-  << FixItHint::CreateReplacement(OpLoc, ".");
-}
-IsArrow = false;
-  } else {
-S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
-<< BaseType << BaseExpr.get()->getSourceRange();
-return ExprError();
+else if (BaseType->isRecordType()) {
+  // Recover from arrow accesses to records, e.g.:
+  //   struct MyRecord foo;
+  //   foo->bar
+  // This is actually well-formed in C++ if MyRecord has an
+  // overloaded operator->, but that should have been dealt with
+  // by now--or a diagnostic message already issued if a problem
+  // was encountered while looking for the overloaded operator->.
+  if (!S.getLangOpts().CPlusPlus) {
+S.Diag(OpLoc, 

[clang] [Clang][Sema] Fix bug where operator-> typo corrects in the current instantiation (PR #91972)

2024-05-13 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

> I think this needs a release note? I know the only case we have right now is 
> because of your other patch, but perhaps this affects elsewhere too?

@erichkeane I don't think we need a release note since the code changes are in 
`LookupMemberExpr`, which prior to #90152 had no valid code path for dependent 
types (and had the assert `assert(!BaseType->isDependentType())` to ensure 
this).

https://github.com/llvm/llvm-project/pull/91972
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix bug where operator-> typo corrects in the current instantiation (PR #91972)

2024-05-13 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/91972
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix bug where operator-> typo corrects in the current instantiation (PR #91972)

2024-05-13 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/91972

>From a013806c0199e260c37bc6b16b600e61e4caa1c9 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Mon, 13 May 2024 10:22:04 -0400
Subject: [PATCH] [Clang][Sema] Fix bug where operator-> typo corrects in the
 current instantiation

---
 clang/lib/Sema/SemaExprMember.cpp  | 10 +-
 .../CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp|  7 +++
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaExprMember.cpp 
b/clang/lib/Sema/SemaExprMember.cpp
index 9fa69da4f9685..ac81d4fd57654 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -995,8 +995,6 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
   // arrow operator was used with a dependent non-pointer object expression,
   // build a CXXDependentScopeMemberExpr.
   if (R.wasNotFoundInCurrentInstantiation() ||
-  (IsArrow && !BaseExprType->isPointerType() &&
-   BaseExprType->isDependentType()) ||
   (R.getLookupName().getCXXOverloadedOperator() == OO_Equal &&
(SS.isSet() ? SS.getScopeRep()->isDependent()
: BaseExprType->isDependentType(
@@ -1322,7 +1320,11 @@ static ExprResult LookupMemberExpr(Sema , LookupResult 
,
 else if (const ObjCObjectPointerType *Ptr =
  BaseType->getAs())
   BaseType = Ptr->getPointeeType();
-else if (!BaseType->isDependentType()) {
+else if (BaseType->isFunctionType())
+  goto fail;
+else if (BaseType->isDependentType())
+  BaseType = S.Context.DependentTy;
+else {
   if (BaseType->isRecordType()) {
 // Recover from arrow accesses to records, e.g.:
 //   struct MyRecord foo;
@@ -1337,8 +1339,6 @@ static ExprResult LookupMemberExpr(Sema , LookupResult 
,
   << FixItHint::CreateReplacement(OpLoc, ".");
 }
 IsArrow = false;
-  } else if (BaseType->isFunctionType()) {
-goto fail;
   } else {
 S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
 << BaseType << BaseExpr.get()->getSourceRange();
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp 
b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
index 1adbc33a701c1..fafd54bde7622 100644
--- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
@@ -551,4 +551,11 @@ namespace N4 {
 
   template void D::instantiated(D); // expected-note {{in instantiation of}}
 
+  template
+  struct Typo {
+void not_instantiated(Typo a) {
+  a->Not_instantiated;
+  a->typo;
+}
+  };
 } // namespace N4

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


[clang] [clang-tools-extra] Reapply "[Clang][Sema] Diagnose class member access expressions naming non-existent members of the current instantiation prior to instantiation in the absence of dependent

2024-05-13 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@ilya-biryukov See #91972

https://github.com/llvm/llvm-project/pull/90152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix bug where operator-> typo corrects in the current instantiation (PR #91972)

2024-05-13 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/91972

Fixes [this 
bug](https://github.com/llvm/llvm-project/pull/90152#issuecomment-2107363977) 
introduced in #90152.

This bug occurs when typo-correction attempts to fix a reference to a 
non-existent member of the current instantiation (even though `operator->` may 
return a different type than the object type). This patch fixes it by simply 
considering the object expression to be `ASTContext::DependentTy` when the 
arrow operator is used with a dependent non-pointer non-function operand (after 
any implicit conversions).

>From f5d456a9f042dd0076d0c6e8244a59c693f41132 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Mon, 13 May 2024 10:22:04 -0400
Subject: [PATCH] [Clang][Sema] Fix bug where operator-> typo corrects in the
 current instantiation

---
 clang/lib/Sema/SemaExprMember.cpp  | 14 +++---
 .../temp/temp.res/temp.dep/temp.dep.type/p4.cpp|  7 +++
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Sema/SemaExprMember.cpp 
b/clang/lib/Sema/SemaExprMember.cpp
index 9fa69da4f9685..a3411b3036d5e 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -995,11 +995,9 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
   // arrow operator was used with a dependent non-pointer object expression,
   // build a CXXDependentScopeMemberExpr.
   if (R.wasNotFoundInCurrentInstantiation() ||
-  (IsArrow && !BaseExprType->isPointerType() &&
-   BaseExprType->isDependentType()) ||
   (R.getLookupName().getCXXOverloadedOperator() == OO_Equal &&
-   (SS.isSet() ? SS.getScopeRep()->isDependent()
-   : BaseExprType->isDependentType(
+  (SS.isSet() ? SS.getScopeRep()->isDependent()
+  : BaseExprType->isDependentType(
 return ActOnDependentMemberExpr(BaseExpr, BaseExprType, IsArrow, OpLoc, SS,
 TemplateKWLoc, FirstQualifierInScope,
 R.getLookupNameInfo(), TemplateArgs);
@@ -1322,7 +1320,11 @@ static ExprResult LookupMemberExpr(Sema , LookupResult 
,
 else if (const ObjCObjectPointerType *Ptr =
  BaseType->getAs())
   BaseType = Ptr->getPointeeType();
-else if (!BaseType->isDependentType()) {
+else if (BaseType->isFunctionType())
+  goto fail;
+else if (BaseType->isDependentType())
+  BaseType = S.Context.DependentTy;
+else {
   if (BaseType->isRecordType()) {
 // Recover from arrow accesses to records, e.g.:
 //   struct MyRecord foo;
@@ -1337,8 +1339,6 @@ static ExprResult LookupMemberExpr(Sema , LookupResult 
,
   << FixItHint::CreateReplacement(OpLoc, ".");
 }
 IsArrow = false;
-  } else if (BaseType->isFunctionType()) {
-goto fail;
   } else {
 S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
 << BaseType << BaseExpr.get()->getSourceRange();
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp 
b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
index 1adbc33a701c1..fafd54bde7622 100644
--- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
@@ -551,4 +551,11 @@ namespace N4 {
 
   template void D::instantiated(D); // expected-note {{in instantiation of}}
 
+  template
+  struct Typo {
+void not_instantiated(Typo a) {
+  a->Not_instantiated;
+  a->typo;
+}
+  };
 } // namespace N4

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


[clang] [clang-tools-extra] Reapply "[Clang][Sema] Diagnose class member access expressions naming non-existent members of the current instantiation prior to instantiation in the absence of dependent

2024-05-13 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@ilya-biryukov I can fix this quickly (less than an hour).

https://github.com/llvm/llvm-project/pull/90152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] Reapply "[Clang][Sema] Diagnose class member access expressions naming non-existent members of the current instantiation prior to instantiation in the absence of dependent

2024-05-13 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

Repro:
```cpp
template
struct Typo {
  Typo(const Typo& t) {   
t->typo; // error
t->Typp; // error
t->Tzpo; // error
t->ty; // ok
  }
};
```

https://github.com/llvm/llvm-project/pull/90152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] Reapply "[Clang][Sema] Diagnose class member access expressions naming non-existent members of the current instantiation prior to instantiation in the absence of dependent

2024-05-13 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@ilya-biryukov Actually, that is an incredibly useful piece of information :) I 
think this is an issue with type correction...

https://github.com/llvm/llvm-project/pull/90152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] Reapply "[Clang] Unify interface for accessing template arguments as written for class/variable template specializations (#81642)" (PR #91393)

2024-05-10 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@adrian-prantl I tested this patch locally and it fixes the crash in LLDB

https://github.com/llvm/llvm-project/pull/91393
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] Reapply "[Clang][Sema] Diagnose class member access expressions naming non-existent members of the current instantiation prior to instantiation in the absence of dependent

2024-05-09 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@dyung Per [[temp.dep.type] p10.11](http://eel.is/c++draft/temp.dep.type#10.11):
> A type is dependent if it is 
> - [...]
> - denoted by a _simple-template-id_ in which either the template name is a 
> template parameter or any of the template arguments is a dependent type or an 
> expression that is type-dependent or value-dependent or is a pack expansion,
> - [...]

In this case, `self` is a typedef for `COneSet` (the injected-class-name of the 
class template). When used as a _type-name_, the injected-class-name of a class 
template is equivalent to a _simple-template-id_ with the template arguments of 
the template parameters of that template. Despite that type _being_ the current 
instantiation, it is still considered to be a dependent type (name lookup has 
special rules when the lookup context is dependent _and_ is the current 
instantiation). 

Since `pSetOther` names a declaration that has a dependent type, 
`SWAP(pSetOther)` is a dependent call.

https://github.com/llvm/llvm-project/pull/90152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Revert changes to operator= lookup in templated classes from #91498, #90999, and #90152 (PR #91620)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/91620
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Revert changes to operator= lookup in templated classes from #91498, #90999, and #90152 (PR #91620)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/91620

>From 7b2f3da17dfc93a4f0aa69ad4da90707b6f2e8b6 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 9 May 2024 12:30:28 -0400
Subject: [PATCH 1/3] Revert "[Clang][Sema] Fix lookup of dependent operator=
 outside of complete-class contexts (#91498)"

This reverts commit 62b5b61f436add042d8729dc9837d055613180d9.
---
 clang/lib/Sema/SemaLookup.cpp | 35 ---
 clang/lib/Sema/SemaTemplate.cpp   |  7 ++--
 .../temp.res/temp.dep/temp.dep.type/p4.cpp| 13 ---
 3 files changed, 20 insertions(+), 35 deletions(-)

diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index e20de338ebb16..e63da5875d2c9 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1267,20 +1267,6 @@ struct FindLocalExternScope {
   LookupResult 
   bool OldFindLocalExtern;
 };
-
-/// Returns true if 'operator=' should be treated as a dependent name.
-bool isDependentAssignmentOperator(DeclarationName Name,
-   DeclContext *LookupContext) {
-  const auto *LookupRecord = dyn_cast_if_present(LookupContext);
-  // If the lookup context is the current instantiation but we are outside a
-  // complete-class context, we will never find the implicitly declared
-  // copy/move assignment operators because they are declared at the closing 
'}'
-  // of the class specifier. In such cases, we treat 'operator=' like any other
-  // unqualified name because the results of name lookup in the template
-  // definition/instantiation context will always be the same.
-  return Name.getCXXOverloadedOperator() == OO_Equal && LookupRecord &&
- !LookupRecord->isBeingDefined() && LookupRecord->isDependentContext();
-}
 } // end anonymous namespace
 
 bool Sema::CppLookupName(LookupResult , Scope *S) {
@@ -1289,6 +1275,13 @@ bool Sema::CppLookupName(LookupResult , Scope *S) {
   DeclarationName Name = R.getLookupName();
   Sema::LookupNameKind NameKind = R.getLookupKind();
 
+  // If this is the name of an implicitly-declared special member function,
+  // go through the scope stack to implicitly declare
+  if (isImplicitlyDeclaredMemberFunctionName(Name)) {
+for (Scope *PreS = S; PreS; PreS = PreS->getParent())
+  if (DeclContext *DC = PreS->getEntity())
+DeclareImplicitMemberFunctionsWithName(*this, Name, R.getNameLoc(), 
DC);
+  }
   // C++23 [temp.dep.general]p2:
   //   The component name of an unqualified-id is dependent if
   //   - it is a conversion-function-id whose conversion-type-id
@@ -1306,8 +1299,9 @@ bool Sema::CppLookupName(LookupResult , Scope *S) {
   if (isImplicitlyDeclaredMemberFunctionName(Name)) {
 for (Scope *PreS = S; PreS; PreS = PreS->getParent())
   if (DeclContext *DC = PreS->getEntity()) {
-if (!R.isTemplateNameLookup() &&
-isDependentAssignmentOperator(Name, DC)) {
+if (DC->isDependentContext() && isa(DC) &&
+Name.getCXXOverloadedOperator() == OO_Equal &&
+!R.isTemplateNameLookup()) {
   R.setNotFoundInCurrentInstantiation();
   return false;
 }
@@ -2478,6 +2472,8 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 }
   } QL(LookupCtx);
 
+  bool TemplateNameLookup = R.isTemplateNameLookup();
+  CXXRecordDecl *LookupRec = dyn_cast(LookupCtx);
   if (!InUnqualifiedLookup && !R.isForRedeclaration()) {
 // C++23 [temp.dep.type]p5:
 //   A qualified name is dependent if
@@ -2490,14 +2486,13 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 if (DeclarationName Name = R.getLookupName();
 (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
  Name.getCXXNameType()->isDependentType()) ||
-(!R.isTemplateNameLookup() &&
- isDependentAssignmentOperator(Name, LookupCtx))) {
+(Name.getCXXOverloadedOperator() == OO_Equal && LookupRec &&
+ LookupRec->isDependentContext() && !TemplateNameLookup)) {
   R.setNotFoundInCurrentInstantiation();
   return false;
 }
   }
 
-  CXXRecordDecl *LookupRec = dyn_cast(LookupCtx);
   if (LookupDirect(*this, R, LookupCtx)) {
 R.resolveKind();
 if (LookupRec)
@@ -2609,7 +2604,7 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 //   template, and if the name is used as a template-name, the
 //   reference refers to the class template itself and not a
 //   specialization thereof, and is not ambiguous.
-if (R.isTemplateNameLookup())
+if (TemplateNameLookup)
   if (auto *TD = getAsTemplateNameDecl(ND))
 ND = TD;
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 480bc74c2001a..7e57fa0696725 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -726,7 +726,7 @@ 

[clang] [Clang][Sema] Revert changes to operator= lookup in templated classes from #91498, #90999, and #90152 (PR #91620)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/91620
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Revert changes to operator= lookup in templated classes from #91498, #90999, and #90152 (PR #91620)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/91620
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Revert "[Clang][Sema] Fix lookup of dependent operator= outside of complete-class contexts (#91498)" (PR #91620)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/91620

>From 7b2f3da17dfc93a4f0aa69ad4da90707b6f2e8b6 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 9 May 2024 12:30:28 -0400
Subject: [PATCH 1/3] Revert "[Clang][Sema] Fix lookup of dependent operator=
 outside of complete-class contexts (#91498)"

This reverts commit 62b5b61f436add042d8729dc9837d055613180d9.
---
 clang/lib/Sema/SemaLookup.cpp | 35 ---
 clang/lib/Sema/SemaTemplate.cpp   |  7 ++--
 .../temp.res/temp.dep/temp.dep.type/p4.cpp| 13 ---
 3 files changed, 20 insertions(+), 35 deletions(-)

diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index e20de338ebb16..e63da5875d2c9 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1267,20 +1267,6 @@ struct FindLocalExternScope {
   LookupResult 
   bool OldFindLocalExtern;
 };
-
-/// Returns true if 'operator=' should be treated as a dependent name.
-bool isDependentAssignmentOperator(DeclarationName Name,
-   DeclContext *LookupContext) {
-  const auto *LookupRecord = dyn_cast_if_present(LookupContext);
-  // If the lookup context is the current instantiation but we are outside a
-  // complete-class context, we will never find the implicitly declared
-  // copy/move assignment operators because they are declared at the closing 
'}'
-  // of the class specifier. In such cases, we treat 'operator=' like any other
-  // unqualified name because the results of name lookup in the template
-  // definition/instantiation context will always be the same.
-  return Name.getCXXOverloadedOperator() == OO_Equal && LookupRecord &&
- !LookupRecord->isBeingDefined() && LookupRecord->isDependentContext();
-}
 } // end anonymous namespace
 
 bool Sema::CppLookupName(LookupResult , Scope *S) {
@@ -1289,6 +1275,13 @@ bool Sema::CppLookupName(LookupResult , Scope *S) {
   DeclarationName Name = R.getLookupName();
   Sema::LookupNameKind NameKind = R.getLookupKind();
 
+  // If this is the name of an implicitly-declared special member function,
+  // go through the scope stack to implicitly declare
+  if (isImplicitlyDeclaredMemberFunctionName(Name)) {
+for (Scope *PreS = S; PreS; PreS = PreS->getParent())
+  if (DeclContext *DC = PreS->getEntity())
+DeclareImplicitMemberFunctionsWithName(*this, Name, R.getNameLoc(), 
DC);
+  }
   // C++23 [temp.dep.general]p2:
   //   The component name of an unqualified-id is dependent if
   //   - it is a conversion-function-id whose conversion-type-id
@@ -1306,8 +1299,9 @@ bool Sema::CppLookupName(LookupResult , Scope *S) {
   if (isImplicitlyDeclaredMemberFunctionName(Name)) {
 for (Scope *PreS = S; PreS; PreS = PreS->getParent())
   if (DeclContext *DC = PreS->getEntity()) {
-if (!R.isTemplateNameLookup() &&
-isDependentAssignmentOperator(Name, DC)) {
+if (DC->isDependentContext() && isa(DC) &&
+Name.getCXXOverloadedOperator() == OO_Equal &&
+!R.isTemplateNameLookup()) {
   R.setNotFoundInCurrentInstantiation();
   return false;
 }
@@ -2478,6 +2472,8 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 }
   } QL(LookupCtx);
 
+  bool TemplateNameLookup = R.isTemplateNameLookup();
+  CXXRecordDecl *LookupRec = dyn_cast(LookupCtx);
   if (!InUnqualifiedLookup && !R.isForRedeclaration()) {
 // C++23 [temp.dep.type]p5:
 //   A qualified name is dependent if
@@ -2490,14 +2486,13 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 if (DeclarationName Name = R.getLookupName();
 (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
  Name.getCXXNameType()->isDependentType()) ||
-(!R.isTemplateNameLookup() &&
- isDependentAssignmentOperator(Name, LookupCtx))) {
+(Name.getCXXOverloadedOperator() == OO_Equal && LookupRec &&
+ LookupRec->isDependentContext() && !TemplateNameLookup)) {
   R.setNotFoundInCurrentInstantiation();
   return false;
 }
   }
 
-  CXXRecordDecl *LookupRec = dyn_cast(LookupCtx);
   if (LookupDirect(*this, R, LookupCtx)) {
 R.resolveKind();
 if (LookupRec)
@@ -2609,7 +2604,7 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 //   template, and if the name is used as a template-name, the
 //   reference refers to the class template itself and not a
 //   specialization thereof, and is not ambiguous.
-if (R.isTemplateNameLookup())
+if (TemplateNameLookup)
   if (auto *TD = getAsTemplateNameDecl(ND))
 ND = TD;
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 480bc74c2001a..7e57fa0696725 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -726,7 +726,7 @@ 

[clang] Revert "[Clang][Sema] Fix lookup of dependent operator= outside of complete-class contexts (#91498)" (PR #91620)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/91620

>From 7b2f3da17dfc93a4f0aa69ad4da90707b6f2e8b6 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 9 May 2024 12:30:28 -0400
Subject: [PATCH 1/4] Revert "[Clang][Sema] Fix lookup of dependent operator=
 outside of complete-class contexts (#91498)"

This reverts commit 62b5b61f436add042d8729dc9837d055613180d9.
---
 clang/lib/Sema/SemaLookup.cpp | 35 ---
 clang/lib/Sema/SemaTemplate.cpp   |  7 ++--
 .../temp.res/temp.dep/temp.dep.type/p4.cpp| 13 ---
 3 files changed, 20 insertions(+), 35 deletions(-)

diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index e20de338ebb16..e63da5875d2c9 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1267,20 +1267,6 @@ struct FindLocalExternScope {
   LookupResult 
   bool OldFindLocalExtern;
 };
-
-/// Returns true if 'operator=' should be treated as a dependent name.
-bool isDependentAssignmentOperator(DeclarationName Name,
-   DeclContext *LookupContext) {
-  const auto *LookupRecord = dyn_cast_if_present(LookupContext);
-  // If the lookup context is the current instantiation but we are outside a
-  // complete-class context, we will never find the implicitly declared
-  // copy/move assignment operators because they are declared at the closing 
'}'
-  // of the class specifier. In such cases, we treat 'operator=' like any other
-  // unqualified name because the results of name lookup in the template
-  // definition/instantiation context will always be the same.
-  return Name.getCXXOverloadedOperator() == OO_Equal && LookupRecord &&
- !LookupRecord->isBeingDefined() && LookupRecord->isDependentContext();
-}
 } // end anonymous namespace
 
 bool Sema::CppLookupName(LookupResult , Scope *S) {
@@ -1289,6 +1275,13 @@ bool Sema::CppLookupName(LookupResult , Scope *S) {
   DeclarationName Name = R.getLookupName();
   Sema::LookupNameKind NameKind = R.getLookupKind();
 
+  // If this is the name of an implicitly-declared special member function,
+  // go through the scope stack to implicitly declare
+  if (isImplicitlyDeclaredMemberFunctionName(Name)) {
+for (Scope *PreS = S; PreS; PreS = PreS->getParent())
+  if (DeclContext *DC = PreS->getEntity())
+DeclareImplicitMemberFunctionsWithName(*this, Name, R.getNameLoc(), 
DC);
+  }
   // C++23 [temp.dep.general]p2:
   //   The component name of an unqualified-id is dependent if
   //   - it is a conversion-function-id whose conversion-type-id
@@ -1306,8 +1299,9 @@ bool Sema::CppLookupName(LookupResult , Scope *S) {
   if (isImplicitlyDeclaredMemberFunctionName(Name)) {
 for (Scope *PreS = S; PreS; PreS = PreS->getParent())
   if (DeclContext *DC = PreS->getEntity()) {
-if (!R.isTemplateNameLookup() &&
-isDependentAssignmentOperator(Name, DC)) {
+if (DC->isDependentContext() && isa(DC) &&
+Name.getCXXOverloadedOperator() == OO_Equal &&
+!R.isTemplateNameLookup()) {
   R.setNotFoundInCurrentInstantiation();
   return false;
 }
@@ -2478,6 +2472,8 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 }
   } QL(LookupCtx);
 
+  bool TemplateNameLookup = R.isTemplateNameLookup();
+  CXXRecordDecl *LookupRec = dyn_cast(LookupCtx);
   if (!InUnqualifiedLookup && !R.isForRedeclaration()) {
 // C++23 [temp.dep.type]p5:
 //   A qualified name is dependent if
@@ -2490,14 +2486,13 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 if (DeclarationName Name = R.getLookupName();
 (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
  Name.getCXXNameType()->isDependentType()) ||
-(!R.isTemplateNameLookup() &&
- isDependentAssignmentOperator(Name, LookupCtx))) {
+(Name.getCXXOverloadedOperator() == OO_Equal && LookupRec &&
+ LookupRec->isDependentContext() && !TemplateNameLookup)) {
   R.setNotFoundInCurrentInstantiation();
   return false;
 }
   }
 
-  CXXRecordDecl *LookupRec = dyn_cast(LookupCtx);
   if (LookupDirect(*this, R, LookupCtx)) {
 R.resolveKind();
 if (LookupRec)
@@ -2609,7 +2604,7 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 //   template, and if the name is used as a template-name, the
 //   reference refers to the class template itself and not a
 //   specialization thereof, and is not ambiguous.
-if (R.isTemplateNameLookup())
+if (TemplateNameLookup)
   if (auto *TD = getAsTemplateNameDecl(ND))
 ND = TD;
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 480bc74c2001a..7e57fa0696725 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -726,7 +726,7 @@ 

[clang] Revert "[Clang][Sema] Fix lookup of dependent operator= outside of complete-class contexts (#91498)" (PR #91620)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

Is it alright to partially revert commits in a single PR? If so, I'm just going 
to revert all the `operator=` related changes from #91498, #90999, and #90152. 

https://github.com/llvm/llvm-project/pull/91620
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Revert "[Clang][Sema] Fix lookup of dependent operator= outside of complete-class contexts (#91498)" (PR #91620)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/91620

This reverts commit 62b5b61f436add042d8729dc9837d055613180d9 (#91498).

>From 7b2f3da17dfc93a4f0aa69ad4da90707b6f2e8b6 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 9 May 2024 12:30:28 -0400
Subject: [PATCH] Revert "[Clang][Sema] Fix lookup of dependent operator=
 outside of complete-class contexts (#91498)"

This reverts commit 62b5b61f436add042d8729dc9837d055613180d9.
---
 clang/lib/Sema/SemaLookup.cpp | 35 ---
 clang/lib/Sema/SemaTemplate.cpp   |  7 ++--
 .../temp.res/temp.dep/temp.dep.type/p4.cpp| 13 ---
 3 files changed, 20 insertions(+), 35 deletions(-)

diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index e20de338ebb1..e63da5875d2c 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1267,20 +1267,6 @@ struct FindLocalExternScope {
   LookupResult 
   bool OldFindLocalExtern;
 };
-
-/// Returns true if 'operator=' should be treated as a dependent name.
-bool isDependentAssignmentOperator(DeclarationName Name,
-   DeclContext *LookupContext) {
-  const auto *LookupRecord = dyn_cast_if_present(LookupContext);
-  // If the lookup context is the current instantiation but we are outside a
-  // complete-class context, we will never find the implicitly declared
-  // copy/move assignment operators because they are declared at the closing 
'}'
-  // of the class specifier. In such cases, we treat 'operator=' like any other
-  // unqualified name because the results of name lookup in the template
-  // definition/instantiation context will always be the same.
-  return Name.getCXXOverloadedOperator() == OO_Equal && LookupRecord &&
- !LookupRecord->isBeingDefined() && LookupRecord->isDependentContext();
-}
 } // end anonymous namespace
 
 bool Sema::CppLookupName(LookupResult , Scope *S) {
@@ -1289,6 +1275,13 @@ bool Sema::CppLookupName(LookupResult , Scope *S) {
   DeclarationName Name = R.getLookupName();
   Sema::LookupNameKind NameKind = R.getLookupKind();
 
+  // If this is the name of an implicitly-declared special member function,
+  // go through the scope stack to implicitly declare
+  if (isImplicitlyDeclaredMemberFunctionName(Name)) {
+for (Scope *PreS = S; PreS; PreS = PreS->getParent())
+  if (DeclContext *DC = PreS->getEntity())
+DeclareImplicitMemberFunctionsWithName(*this, Name, R.getNameLoc(), 
DC);
+  }
   // C++23 [temp.dep.general]p2:
   //   The component name of an unqualified-id is dependent if
   //   - it is a conversion-function-id whose conversion-type-id
@@ -1306,8 +1299,9 @@ bool Sema::CppLookupName(LookupResult , Scope *S) {
   if (isImplicitlyDeclaredMemberFunctionName(Name)) {
 for (Scope *PreS = S; PreS; PreS = PreS->getParent())
   if (DeclContext *DC = PreS->getEntity()) {
-if (!R.isTemplateNameLookup() &&
-isDependentAssignmentOperator(Name, DC)) {
+if (DC->isDependentContext() && isa(DC) &&
+Name.getCXXOverloadedOperator() == OO_Equal &&
+!R.isTemplateNameLookup()) {
   R.setNotFoundInCurrentInstantiation();
   return false;
 }
@@ -2478,6 +2472,8 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 }
   } QL(LookupCtx);
 
+  bool TemplateNameLookup = R.isTemplateNameLookup();
+  CXXRecordDecl *LookupRec = dyn_cast(LookupCtx);
   if (!InUnqualifiedLookup && !R.isForRedeclaration()) {
 // C++23 [temp.dep.type]p5:
 //   A qualified name is dependent if
@@ -2490,14 +2486,13 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 if (DeclarationName Name = R.getLookupName();
 (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
  Name.getCXXNameType()->isDependentType()) ||
-(!R.isTemplateNameLookup() &&
- isDependentAssignmentOperator(Name, LookupCtx))) {
+(Name.getCXXOverloadedOperator() == OO_Equal && LookupRec &&
+ LookupRec->isDependentContext() && !TemplateNameLookup)) {
   R.setNotFoundInCurrentInstantiation();
   return false;
 }
   }
 
-  CXXRecordDecl *LookupRec = dyn_cast(LookupCtx);
   if (LookupDirect(*this, R, LookupCtx)) {
 R.resolveKind();
 if (LookupRec)
@@ -2609,7 +2604,7 @@ bool Sema::LookupQualifiedName(LookupResult , 
DeclContext *LookupCtx,
 //   template, and if the name is used as a template-name, the
 //   reference refers to the class template itself and not a
 //   specialization thereof, and is not ambiguous.
-if (R.isTemplateNameLookup())
+if (TemplateNameLookup)
   if (auto *TD = getAsTemplateNameDecl(ND))
 ND = TD;
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 480bc74c2001..7e57fa069672 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ 

[clang] [Clang][Sema] Fix lookup of dependent operator= outside of complete-class contexts (PR #91498)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@aeubanks I think I'm going to revert this & maybe partially revert the changes 
in #90152 which cause `operator=` to be treated as a dependent name when the 
current class is templated. There are lots of edge cases that need to be 
accounted for. Thoughts @erichkeane ?

https://github.com/llvm/llvm-project/pull/91498
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix lookup of dependent operator= outside of complete-class contexts (PR #91498)

2024-05-09 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@glandium I've reduced it to the following:
```cpp
template
struct A
{
static constexpr bool B = true;
};

template
struct C { };

template
struct D
{
C::B> f();
};

template
auto D::f() -> C::B> { }
```
The problem is that we build a `DependentScopeDeclRefExpr` for `A::B` in the 
first declaration of `f`, and a `CXXDependentScopeMemberExpr` for the second 
declaration of `f`. 

Since we have no idea whether `A::B` will be an implicit member access, I 
think that the correct behavior is that `ActOnDependentIdExpression` should 
_never_ build a `CXXDependentScopeMemberExpr`.

https://github.com/llvm/llvm-project/pull/91498
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)

2024-05-08 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@erichkeane Release note added

https://github.com/llvm/llvm-project/pull/91534
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   6   7   >