Skip to content

Commit 6b48a5a

Browse files
committed
[clang] Apply more missing changes from several Sema-related commits
cherry-picked: 9e1f1cf [email protected] Tue Jul 9 16:40:53 2024 -0400 [Clang][Sema] Handle class member access expressions with valid nested-name-specifiers that become invalid after lookup (llvm#98167) 584e431 [email protected] Wed Jul 3 12:12:53 2024 -0400 [Clang][Sema] Treat explicit specializations of static data member templates declared without 'static' as static data members when diagnosing uses of 'auto' (llvm#97425) a1bce0b [email protected] Thu Jun 27 08:17:40 2024 -0700 Clang: Add warning flag for storage class specifiers on explicit specializations (llvm#96699) f46d146 [email protected] Fri May 31 11:02:21 2024 -0700 [clang] require template arg list after template kw (llvm#80801) 033ec09 [email protected] Fri Dec 22 09:00:41 2023 +0800 [Clang][Sema] Fix Wswitch-default bad warning in template (llvm#76007) c281782 [email protected] Thu Dec 7 09:03:15 2023 +0800 [clang][Sema] Add -Wswitch-default warning option (llvm#73077) Change-Id: Ib2582201b01cc62c3bf62011347925556e8531f7
1 parent aee908e commit 6b48a5a

File tree

20 files changed

+119
-68
lines changed

20 files changed

+119
-68
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ Resolutions to C++ Defect Reports
260260
- Reject explicit object parameters with type ``void`` (``this void``).
261261
(`CWG2915: Explicit object parameters of type void <https://cplusplus.github.io/CWG/issues/2915.html>`_).
262262

263+
- Clang now requires a template argument list after a template keyword.
264+
(`CWG96: Syntactic disambiguation using the template keyword <https://cplusplus.github.io/CWG/issues/96.html>`_).
265+
263266
- Clang now allows trailing requires clause on explicit deduction guides.
264267
(`CWG2707: Deduction guides cannot have a trailing requires-clause <https://cplusplus.github.io/CWG/issues/2707.html>`_).
265268

@@ -389,6 +392,9 @@ Attribute Changes in Clang
389392
Improvements to Clang's diagnostics
390393
-----------------------------------
391394

395+
- Clang's ``-Wswitch-default`` flag now diagnoses whenever a ``switch`` statement
396+
does not have a ``default`` label.
397+
392398
- Some template related diagnostics have been improved.
393399

394400
.. code-block:: c++

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor,
674674

675675
def : DiagGroup<"sign-promo">;
676676
def SignCompare : DiagGroup<"sign-compare">;
677-
def : DiagGroup<"switch-default">;
677+
def SwitchDefault : DiagGroup<"switch-default">;
678678
def : DiagGroup<"synth">;
679679
def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
680680
def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">;

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,6 @@ def err_requires_expr_in_simple_requirement : Error<
902902
"requires expression in requirement body; did "
903903
"you intend to place it in a nested requirement? (add another 'requires' "
904904
"before the expression)">;
905-
906905
def missing_template_arg_list_after_template_kw : Extension<
907906
"a template argument list is expected after a name prefixed by the template "
908907
"keyword">, InGroup<DiagGroup<"missing-template-arg-list-after-template-kw">>,

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10348,6 +10348,8 @@ def warn_missing_case : Warning<"%plural{"
1034810348
"3:enumeration values %1, %2, and %3 not handled in switch|"
1034910349
":%0 enumeration values not handled in switch: %1, %2, %3...}0">,
1035010350
InGroup<Switch>;
10351+
def warn_switch_default : Warning<"'switch' missing 'default' label">,
10352+
InGroup<SwitchDefault>, DefaultIgnore;
1035110353

1035210354
def warn_unannotated_fallthrough : Warning<
1035310355
"unannotated fall-through between switch labels">,

clang/lib/Parse/ParseExprCXX.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "clang/AST/DeclTemplate.h"
1515
#include "clang/AST/ExprCXX.h"
1616
#include "clang/Basic/PrettyStackTrace.h"
17+
#include "clang/Basic/TemplateKinds.h"
1718
#include "clang/Basic/TokenKinds.h"
1819
#include "clang/Lex/LiteralSupport.h"
1920
#include "clang/Parse/ParseDiagnostic.h"
@@ -3036,12 +3037,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
30363037
SS, ObjectType, ObjectHadErrors,
30373038
TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
30383039
EnteringContext, Result, TemplateSpecified);
3039-
else if (TemplateSpecified &&
3040-
Actions.ActOnTemplateName(
3041-
getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
3042-
EnteringContext, Template,
3043-
/*AllowInjectedClassName*/ true) == TNK_Non_template)
3044-
return true;
3040+
3041+
if (TemplateSpecified) {
3042+
TemplateNameKind TNK =
3043+
Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
3044+
ObjectType, EnteringContext, Template,
3045+
/*AllowInjectedClassName=*/true);
3046+
if (TNK == TNK_Non_template)
3047+
return true;
3048+
3049+
// C++2c [tem.names]p6
3050+
// A name prefixed by the keyword template shall be followed by a template
3051+
// argument list or refer to a class template or an alias template.
3052+
if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name ||
3053+
TNK == TNK_Var_template) &&
3054+
!Tok.is(tok::less))
3055+
Diag(IdLoc, diag::missing_template_arg_list_after_template_kw);
3056+
}
30453057
return false;
30463058
}
30473059

clang/lib/Sema/SemaExprMember.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -790,9 +790,6 @@ ExprResult Sema::BuildMemberReferenceExpr(
790790
ActOnMemberAccessExtraArgs *ExtraArgs) {
791791
LookupResult R(*this, NameInfo, LookupMemberName);
792792

793-
if (SS.isInvalid())
794-
return ExprError();
795-
796793
// Implicit member accesses.
797794
if (!Base) {
798795
TypoExpr *TE = nullptr;
@@ -827,6 +824,11 @@ ExprResult Sema::BuildMemberReferenceExpr(
827824
BaseType = Base->getType();
828825
}
829826

827+
// BuildMemberReferenceExpr expects the nested-name-specifier, if any, to be
828+
// valid.
829+
if (SS.isInvalid())
830+
return ExprError();
831+
830832
return BuildMemberReferenceExpr(Base, BaseType,
831833
OpLoc, IsArrow, SS, TemplateKWLoc,
832834
FirstQualifierInScope, R, TemplateArgs, S,
@@ -1746,14 +1748,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
17461748

17471749
ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
17481750
SourceLocation OpLoc,
1749-
tok::TokenKind OpKind,
1750-
CXXScopeSpec &SS,
1751+
tok::TokenKind OpKind, CXXScopeSpec &SS,
17511752
SourceLocation TemplateKWLoc,
1752-
UnqualifiedId &Id,
1753-
Decl *ObjCImpDecl) {
1754-
if (SS.isSet() && SS.isInvalid())
1755-
return ExprError();
1756-
1753+
UnqualifiedId &Id, Decl *ObjCImpDecl) {
17571754
// Warn about the explicit constructor calls Microsoft extension.
17581755
if (getLangOpts().MicrosoftExt &&
17591756
Id.getKind() == UnqualifiedIdKind::IK_ConstructorName)

clang/lib/Sema/SemaStmt.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,10 +1384,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
13841384
assert(!HasConstantCond ||
13851385
(ConstantCondValue.getBitWidth() == CondWidth &&
13861386
ConstantCondValue.isSigned() == CondIsSigned));
1387-
#if NEEDS_PATCH_FOR_SWITCH
1388-
//[clang][Sema] Add -Wswitch-default warning option (#73077)
13891387
Diag(SwitchLoc, diag::warn_switch_default);
1390-
#endif
13911388
}
13921389
bool ShouldCheckConstantCond = HasConstantCond;
13931390

clang/lib/Sema/SemaType.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3224,8 +3224,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
32243224
break;
32253225
}
32263226
case DeclaratorContext::Member: {
3227-
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
3228-
D.isFunctionDeclarator())
3227+
if (D.isStaticMember() || D.isFunctionDeclarator())
32293228
break;
32303229
bool Cxx = SemaRef.getLangOpts().CPlusPlus;
32313230
if (isa<ObjCContainerDecl>(SemaRef.CurContext)) {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -verify -Wno-unused %s
2+
3+
struct A {
4+
int y;
5+
};
6+
7+
struct B; // expected-note 4{{forward declaration of 'B'}}
8+
9+
void f(A *a, B *b) {
10+
a->B::x; // expected-error {{incomplete type 'B' named in nested name specifier}}
11+
a->A::x; // expected-error {{no member named 'x' in 'A'}}
12+
a->A::y;
13+
b->B::x; // expected-error {{member access into incomplete type 'B'}}
14+
b->A::x; // expected-error {{member access into incomplete type 'B'}}
15+
b->A::y; // expected-error {{member access into incomplete type 'B'}}
16+
}

clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p1.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify %s
1+
// RUN: %clang_cc1 -fsyntax-only -verify=expected,spec %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-explicit-specialization-storage-class %s
23

34
// A storage-class-specifier shall not be specified in an explicit
45
// specialization (14.7.3) or an explicit instantiation (14.7.2)
@@ -7,13 +8,13 @@ template<typename T> void f(T) {}
78
template<typename T> static void g(T) {}
89

910

10-
template<> static void f<int>(int); // expected-warning{{explicit specialization cannot have a storage class}}
11+
template<> static void f<int>(int); // spec-warning{{explicit specialization cannot have a storage class}}
1112
template static void f<float>(float); // expected-error{{explicit instantiation cannot have a storage class}}
1213

1314
template<> void f<double>(double);
1415
template void f<long>(long);
1516

16-
template<> static void g<int>(int); // expected-warning{{explicit specialization cannot have a storage class}}
17+
template<> static void g<int>(int); // spec-warning{{explicit specialization cannot have a storage class}}
1718
template static void g<float>(float); // expected-error{{explicit instantiation cannot have a storage class}}
1819

1920
template<> void g<double>(double);
@@ -29,5 +30,12 @@ int X<T>::value = 17;
2930

3031
template static int X<int>::value; // expected-error{{explicit instantiation cannot have a storage class}}
3132

32-
template<> static int X<float>::value; // expected-warning{{explicit specialization cannot have a storage class}}
33+
template<> static int X<float>::value; // spec-warning{{explicit specialization cannot have a storage class}}
3334
// expected-error@-1{{'static' can only be specified inside the class definition}}
35+
36+
struct t1 {
37+
template<typename>
38+
static void f1();
39+
template<>
40+
static void f1<int>(); // spec-warning{{explicit specialization cannot have a storage class}}
41+
};

0 commit comments

Comments
 (0)