r237383 - DR295: cv-qualifiers on function types are ignored in C++.
Richard Smith
richard-llvm at metafoo.co.uk
Thu May 14 12:10:43 PDT 2015
Author: rsmith
Date: Thu May 14 14:10:42 2015
New Revision: 237383
URL: http://llvm.org/viewvc/llvm-project?rev=237383&view=rev
Log:
DR295: cv-qualifiers on function types are ignored in C++.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/CXX/drs/dr2xx.cpp
cfe/trunk/www/cxx_dr_status.html
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=237383&r1=237382&r2=237383&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 14 14:10:42 2015
@@ -4155,8 +4155,11 @@ def err_typecheck_negative_array_size :
def warn_typecheck_negative_array_new_size : Warning<"array size is negative">,
// FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
InGroup<BadArrayNewLength>;
-def warn_typecheck_function_qualifiers : Warning<
- "qualifier on function type %0 has unspecified behavior">;
+def warn_typecheck_function_qualifiers_ignored : Warning<
+ "'%0' qualifier on function type %1 has no effect">,
+ InGroup<IgnoredQualifiers>;
+def warn_typecheck_function_qualifiers_unspecified : Warning<
+ "'%0' qualifier on function type %1 has unspecified behavior">;
def warn_typecheck_reference_qualifiers : Warning<
"'%0' qualifier on reference type %1 has no effect">,
InGroup<IgnoredQualifiers>;
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=237383&r1=237382&r2=237383&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu May 14 14:10:42 2015
@@ -688,6 +688,33 @@ static void maybeSynthesizeBlockSignatur
state.setCurrentChunkIndex(declarator.getNumTypeObjects());
}
+void diagnoseAndRemoveTypeQualifiers(Sema &S, const DeclSpec &DS,
+ unsigned &TypeQuals, QualType TypeSoFar,
+ unsigned RemoveTQs, unsigned DiagID) {
+ // If this occurs outside a template instantiation, warn the user about
+ // it; they probably didn't mean to specify a redundant qualifier.
+ typedef std::pair<DeclSpec::TQ, SourceLocation> QualLoc;
+ QualLoc Quals[] = {
+ QualLoc(DeclSpec::TQ_const, DS.getConstSpecLoc()),
+ QualLoc(DeclSpec::TQ_volatile, DS.getVolatileSpecLoc()),
+ QualLoc(DeclSpec::TQ_atomic, DS.getAtomicSpecLoc())
+ };
+
+ for (unsigned I = 0, N = llvm::array_lengthof(Quals); I != N; ++I) {
+ if (!(RemoveTQs & Quals[I].first))
+ continue;
+
+ if (S.ActiveTemplateInstantiations.empty()) {
+ if (TypeQuals & Quals[I].first)
+ S.Diag(Quals[I].second, DiagID)
+ << DeclSpec::getSpecifierName(Quals[I].first) << TypeSoFar
+ << FixItHint::CreateRemoval(Quals[I].second);
+ }
+
+ TypeQuals &= ~Quals[I].first;
+ }
+}
+
/// \brief Convert the specified declspec to the appropriate type
/// object.
/// \param state Specifies the declarator containing the declaration specifier
@@ -1117,24 +1144,22 @@ static QualType ConvertDeclSpecToType(Ty
// Apply const/volatile/restrict qualifiers to T.
if (unsigned TypeQuals = DS.getTypeQualifiers()) {
-
- // Warn about CV qualifiers on functions: C99 6.7.3p8: "If the specification
- // of a function type includes any type qualifiers, the behavior is
- // undefined."
- if (Result->isFunctionType() && TypeQuals) {
- if (TypeQuals & DeclSpec::TQ_const)
- S.Diag(DS.getConstSpecLoc(), diag::warn_typecheck_function_qualifiers)
- << Result << DS.getSourceRange();
- else if (TypeQuals & DeclSpec::TQ_volatile)
- S.Diag(DS.getVolatileSpecLoc(),
- diag::warn_typecheck_function_qualifiers)
- << Result << DS.getSourceRange();
- else {
- assert((TypeQuals & (DeclSpec::TQ_restrict | DeclSpec::TQ_atomic)) &&
- "Has CVRA quals but not C, V, R, or A?");
- // No diagnostic; we'll diagnose 'restrict' or '_Atomic' applied to a
- // function type later, in BuildQualifiedType.
- }
+ // Warn about CV qualifiers on function types.
+ // C99 6.7.3p8:
+ // If the specification of a function type includes any type qualifiers,
+ // the behavior is undefined.
+ // C++11 [dcl.fct]p7:
+ // The effect of a cv-qualifier-seq in a function declarator is not the
+ // same as adding cv-qualification on top of the function type. In the
+ // latter case, the cv-qualifiers are ignored.
+ if (TypeQuals && Result->isFunctionType()) {
+ diagnoseAndRemoveTypeQualifiers(
+ S, DS, TypeQuals, Result, DeclSpec::TQ_const | DeclSpec::TQ_volatile,
+ S.getLangOpts().CPlusPlus
+ ? diag::warn_typecheck_function_qualifiers_ignored
+ : diag::warn_typecheck_function_qualifiers_unspecified);
+ // No diagnostic for 'restrict' or '_Atomic' applied to a
+ // function type; we'll diagnose those later, in BuildQualifiedType.
}
// C++11 [dcl.ref]p1:
@@ -1145,25 +1170,11 @@ static QualType ConvertDeclSpecToType(Ty
// There don't appear to be any other contexts in which a cv-qualified
// reference type could be formed, so the 'ill-formed' clause here appears
// to never happen.
- if (DS.getTypeSpecType() == DeclSpec::TST_typename &&
- TypeQuals && Result->isReferenceType()) {
- // If this occurs outside a template instantiation, warn the user about
- // it; they probably didn't mean to specify a redundant qualifier.
- typedef std::pair<DeclSpec::TQ, SourceLocation> QualLoc;
- QualLoc Quals[] = {
- QualLoc(DeclSpec::TQ_const, DS.getConstSpecLoc()),
- QualLoc(DeclSpec::TQ_volatile, DS.getVolatileSpecLoc()),
- QualLoc(DeclSpec::TQ_atomic, DS.getAtomicSpecLoc())
- };
- for (unsigned I = 0, N = llvm::array_lengthof(Quals); I != N; ++I) {
- if (S.ActiveTemplateInstantiations.empty()) {
- if (TypeQuals & Quals[I].first)
- S.Diag(Quals[I].second, diag::warn_typecheck_reference_qualifiers)
- << DeclSpec::getSpecifierName(Quals[I].first) << Result
- << FixItHint::CreateRemoval(Quals[I].second);
- }
- TypeQuals &= ~Quals[I].first;
- }
+ if (TypeQuals && Result->isReferenceType()) {
+ diagnoseAndRemoveTypeQualifiers(
+ S, DS, TypeQuals, Result,
+ DeclSpec::TQ_const | DeclSpec::TQ_volatile | DeclSpec::TQ_atomic,
+ diag::warn_typecheck_reference_qualifiers);
}
// C90 6.5.3 constraints: "The same type qualifier shall not appear more
Modified: cfe/trunk/test/CXX/drs/dr2xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr2xx.cpp?rev=237383&r1=237382&r2=237383&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr2xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr2xx.cpp Thu May 14 14:10:42 2015
@@ -999,15 +999,20 @@ namespace dr294 { // dr294: no
}
}
-namespace dr295 { // dr295: no
+namespace dr295 { // dr295: 3.7
typedef int f();
- // FIXME: This warning is incorrect.
- const f g; // expected-warning {{unspecified behavior}}
- const f &r = g; // expected-warning {{unspecified behavior}}
+ const f g; // expected-warning {{'const' qualifier on function type 'f' (aka 'int ()') has no effect}}
+ f &r = g;
template<typename T> struct X {
const T &f;
};
- X<f> x = {g}; // FIXME: expected-error {{drops qualifiers}}
+ X<f> x = {g};
+
+ typedef int U();
+ typedef const U U; // expected-warning {{'const' qualifier on function type 'U' (aka 'int ()') has no effect}}
+
+ typedef int (*V)();
+ typedef volatile U *V; // expected-warning {{'volatile' qualifier on function type 'U' (aka 'int ()') has no effect}}
}
namespace dr296 { // dr296: yes
Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=237383&r1=237382&r2=237383&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Thu May 14 14:10:42 2015
@@ -1811,7 +1811,7 @@ of class templates</td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#295">295</a></td>
<td>CD1</td>
<td>cv-qualifiers on function types</td>
- <td class="none" align="center">No</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr id="296">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#296">296</a></td>
More information about the cfe-commits
mailing list