aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaType.cpp31
-rw-r--r--test/SemaCXX/conditional-expr.cpp5
-rw-r--r--test/SemaCXX/friend.cpp2
4 files changed, 31 insertions, 9 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index edd0dcb915..d73f80a2e9 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -121,7 +121,7 @@ def warn_use_out_of_scope_declaration : Warning<
def err_inline_non_function : Error<
"'inline' can only appear on functions">;
def warn_qual_return_type : Warning<
- "type qualifier on return type has no effect">;
+ "'%0' type qualifier%s1 on return type %plural{1:has|:have}1 no effect">;
def warn_decl_shadow :
Warning<"declaration shadows a %select{"
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index dc3cea1a3c..a4fc98cd95 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1135,17 +1135,34 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
(!getLangOptions().CPlusPlus ||
(!T->isDependentType() && !T->isRecordType()))) {
unsigned Quals = D.getDeclSpec().getTypeQualifiers();
+ std::string QualStr;
+ unsigned NumQuals = 0;
SourceLocation Loc;
- if (Quals & Qualifiers::Const)
+ if (Quals & Qualifiers::Const) {
Loc = D.getDeclSpec().getConstSpecLoc();
- else if (Quals & Qualifiers::Volatile)
- Loc = D.getDeclSpec().getVolatileSpecLoc();
- else {
- assert((Quals & Qualifiers::Restrict) && "Unknown type qualifier");
- Loc = D.getDeclSpec().getRestrictSpecLoc();
+ ++NumQuals;
+ QualStr = "const";
+ }
+ if (Quals & Qualifiers::Volatile) {
+ if (NumQuals == 0) {
+ Loc = D.getDeclSpec().getVolatileSpecLoc();
+ QualStr = "volatile";
+ } else
+ QualStr += " volatile";
+ ++NumQuals;
}
-
+ if (Quals & Qualifiers::Restrict) {
+ if (NumQuals == 0) {
+ Loc = D.getDeclSpec().getRestrictSpecLoc();
+ QualStr = "restrict";
+ } else
+ QualStr += " restrict";
+ ++NumQuals;
+ }
+ assert(NumQuals > 0 && "No known qualifiers?");
+
SemaDiagnosticBuilder DB = Diag(Loc, diag::warn_qual_return_type);
+ DB << QualStr << NumQuals;
if (Quals & Qualifiers::Const)
DB << FixItHint::CreateRemoval(D.getDeclSpec().getConstSpecLoc());
if (Quals & Qualifiers::Volatile)
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 9cbc324467..f37ccc8a15 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -292,10 +292,15 @@ namespace PR7598 {
return v;
}
+ const volatile Enum g2() { // expected-warning{{'const volatile' type qualifiers on return type have no effect}}
+ return v;
+ }
+
void f() {
const Enum v2 = v;
Enum e = false ? g() : v;
Enum e2 = false ? v2 : v;
+ Enum e3 = false ? g2() : v;
}
}
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
index ba34efe36c..65e0da761c 100644
--- a/test/SemaCXX/friend.cpp
+++ b/test/SemaCXX/friend.cpp
@@ -44,7 +44,7 @@ namespace test2 {
// PR5134
namespace test3 {
class Foo {
- friend const int getInt(int inInt = 0); // expected-warning{{type qualifier on return type has no effect}}
+ friend const int getInt(int inInt = 0); // expected-warning{{'const' type qualifier on return type has no effect}}
};
}