Skip to content

Commit 42b99e0

Browse files
committed
Disallow decltype in qualified declarator-ids.
llvm-svn: 146480
1 parent 357362d commit 42b99e0

File tree

4 files changed

+38
-4
lines changed

4 files changed

+38
-4
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,8 @@ def err_cannot_determine_declared_type_of_overloaded_function : Error<
11441144
def warn_cxx98_compat_decltype : Warning<
11451145
"'decltype' type specifier is incompatible with C++98">,
11461146
InGroup<CXX98Compat>, DefaultIgnore;
1147+
def err_decltype_in_declarator : Error<
1148+
"'decltype' cannot be used to name a declaration">;
11471149

11481150
// C++11 auto
11491151
def warn_cxx98_compat_auto_type_specifier : Warning<

clang/lib/Sema/SemaDecl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,6 +3203,16 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D,
32033203
(S->getFlags() & Scope::TemplateParamScope) != 0)
32043204
S = S->getParent();
32053205

3206+
if (NestedNameSpecifierLoc SpecLoc =
3207+
D.getCXXScopeSpec().getWithLocInContext(Context)) {
3208+
while (SpecLoc.getPrefix())
3209+
SpecLoc = SpecLoc.getPrefix();
3210+
if (dyn_cast_or_null<DecltypeType>(
3211+
SpecLoc.getNestedNameSpecifier()->getAsType()))
3212+
Diag(SpecLoc.getBeginLoc(), diag::err_decltype_in_declarator)
3213+
<< SpecLoc.getTypeLoc().getSourceRange();
3214+
}
3215+
32063216
DeclContext *DC = CurContext;
32073217
if (D.getCXXScopeSpec().isInvalid())
32083218
D.setInvalidType();
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2+
3+
// The nested-name-specifier of a qualified declarator-id shall not begin with a decltype-specifier.
4+
class foo {
5+
static int i;
6+
void func();
7+
};
8+
9+
int decltype(foo())::i; // expected-error{{'decltype' cannot be used to name a declaration}}
10+
void decltype(foo())::func() { // expected-error{{'decltype' cannot be used to name a declaration}}
11+
}
12+
13+
14+
template<typename T>
15+
class tfoo {
16+
static int i;
17+
void func();
18+
};
19+
20+
template<typename T>
21+
int decltype(tfoo<T>())::i; // expected-error{{'decltype' cannot be used to name a declaration}} \
22+
expected-error{{nested name specifier 'decltype(tfoo<T>())::' for declaration does not refer into a class, class template or class template partial specialization}}
23+
template<typename T>
24+
void decltype(tfoo<T>())::func() { // expected-error{{'decltype' cannot be used to name a declaration}} \
25+
expected-error{{nested name specifier 'decltype(tfoo<T>())::' for declaration does not refer into a class, class template or class template partial specialization}}
26+
}

clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ namespace PR10127 {
2828
int (decltype(outer())::middle::inner::*p)());
2929
};
3030

31-
int decltype(outer::middle())::inner::func() {
32-
return 0;
33-
}
34-
3531
decltype(outer::middle::inner()) a;
3632
void scope() {
3733
a.decltype(outer::middle())::mfunc(); // expected-error{{'PR10127::outer::middle::mfunc' is not a member of class 'decltype(outer::middle::inner())'}}

0 commit comments

Comments
 (0)