forked from OSchip/llvm-project
-Wc++98-compat and -Wc++98-compat-pedantic warnings for Sema, part 1.
llvm-svn: 142419
This commit is contained in:
parent
b274318bba
commit
0bf8a492fd
|
@ -192,6 +192,9 @@ def err_using_decl_can_not_refer_to_namespace : Error<
|
|||
"using declaration can not refer to namespace">;
|
||||
def err_using_decl_constructor : Error<
|
||||
"using declaration can not refer to a constructor">;
|
||||
def warn_cxx98_compat_using_decl_constructor : Warning<
|
||||
"inherited constructors are incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_using_decl_destructor : Error<
|
||||
"using declaration can not refer to a destructor">;
|
||||
def err_using_decl_template_id : Error<
|
||||
|
@ -623,6 +626,9 @@ def ext_nonclass_type_friend : ExtWarn<
|
|||
"non-class friend type %0 is a C++11 extension">, InGroup<CXX11>;
|
||||
def err_friend_is_member : Error<
|
||||
"friends cannot be members of the declaring class">;
|
||||
def warn_cxx98_compat_friend_is_member : Warning<
|
||||
"friend declaration naming a member of the declaring class is incompatible "
|
||||
"with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def ext_unelaborated_friend_type : ExtWarn<
|
||||
"specify '%select{struct|union|class|enum}0' to befriend %1; accepted "
|
||||
"as a C++11 extension">, InGroup<CXX11>;
|
||||
|
@ -1160,8 +1166,11 @@ def err_incomplete_type_no_underlying_type : Error<
|
|||
"an incomplete enumeration type has no underlying type yet">;
|
||||
|
||||
// C++11 delegating constructors
|
||||
def err_delegation_0x_only : Error<
|
||||
def err_delegating_ctor : Error<
|
||||
"delegating constructors are permitted only in C++11">;
|
||||
def warn_cxx98_compat_delegating_ctor : Warning<
|
||||
"delegating constructors are incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_delegating_initializer_alone : Error<
|
||||
"an initializer for a delegating constructor must appear alone">;
|
||||
def warn_delegating_ctor_cycle : Warning<
|
||||
|
@ -2071,6 +2080,9 @@ def err_template_param_default_arg_missing : Error<
|
|||
def ext_template_parameter_default_in_function_template : ExtWarn<
|
||||
"default template arguments for a function template are a C++11 extension">,
|
||||
InGroup<CXX11>;
|
||||
def warn_cxx98_compat_template_parameter_default_in_function_template : Warning<
|
||||
"default template arguments for a function template are incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_template_parameter_default_template_member : Error<
|
||||
"cannot add a default template argument to the definition of a member of a "
|
||||
"class template">;
|
||||
|
@ -2111,6 +2123,12 @@ def ext_template_arg_local_type : ExtWarn<
|
|||
"template argument uses local type %0">, InGroup<LocalTypeTemplateArgs>;
|
||||
def ext_template_arg_unnamed_type : ExtWarn<
|
||||
"template argument uses unnamed type">, InGroup<UnnamedTypeTemplateArgs>;
|
||||
def warn_cxx98_compat_template_arg_local_type : Warning<
|
||||
"local type %0 as template argument is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def warn_cxx98_compat_template_arg_unnamed_type : Warning<
|
||||
"unnamed type as template argument is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def note_template_unnamed_type_here : Note<
|
||||
"unnamed type used in template argument was declared here">;
|
||||
def err_template_arg_overload_type : Error<
|
||||
|
@ -2178,6 +2196,9 @@ def err_template_arg_not_pointer_to_member_form : Error<
|
|||
"non-type template argument is not a pointer to member constant">;
|
||||
def ext_template_arg_extra_parens : ExtWarn<
|
||||
"address non-type template argument cannot be surrounded by parentheses">;
|
||||
def warn_cxx98_compat_template_arg_extra_parens : Warning<
|
||||
"redundant parentheses surrounding address non-type template argument are "
|
||||
"incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_pointer_to_member_type : Error<
|
||||
"invalid use of pointer to member type after %select{.*|->*}0">;
|
||||
def err_pointer_to_member_call_drops_quals : Error<
|
||||
|
@ -2203,11 +2224,6 @@ def err_template_spec_decl_out_of_scope_global : Error<
|
|||
"%select{class template|class template partial|function template|member "
|
||||
"function|static data member|member class}0 specialization of %1 must "
|
||||
"originally be declared in the global scope">;
|
||||
def ext_template_spec_decl_out_of_scope_global : ExtWarn<
|
||||
"%select{class template|class template partial|function template|member "
|
||||
"function|static data member|member class}0 specialization of %1 must "
|
||||
"originally be declared in the global scope; accepted as a C++11 extension">,
|
||||
InGroup<CXX11>;
|
||||
def err_template_spec_decl_out_of_scope : Error<
|
||||
"%select{class template|class template partial|function template|member "
|
||||
"function|static data member|member class}0 specialization of %1 must "
|
||||
|
@ -2217,6 +2233,11 @@ def ext_template_spec_decl_out_of_scope : ExtWarn<
|
|||
"function|static data member|member class}0 specialization of %1 must "
|
||||
"originally be declared in namespace %2; accepted as a C++11 extension">,
|
||||
InGroup<CXX11>;
|
||||
def warn_cxx98_compat_template_spec_decl_out_of_scope : Warning<
|
||||
"%select{class template|class template partial|function template|member "
|
||||
"function|static data member|member class}0 specialization of %1 outside "
|
||||
"namespace %2 is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_template_spec_redecl_out_of_scope : Error<
|
||||
"%select{class template|class template partial|function template|member "
|
||||
"function|static data member|member class}0 specialization of %1 not in a "
|
||||
|
@ -2384,6 +2405,10 @@ def ext_explicit_instantiation_after_specialization : Extension<
|
|||
"explicit instantiation of %0 that occurs after an explicit "
|
||||
"specialization will be ignored (C++11 extension)">,
|
||||
InGroup<CXX11>;
|
||||
def warn_cxx98_compat_explicit_instantiation_after_specialization : Warning<
|
||||
"explicit instantiation of %0 that occurs after an explicit "
|
||||
"specialization is incompatible with C++98">,
|
||||
InGroup<CXX98CompatPedantic>, DefaultIgnore;
|
||||
def note_previous_template_specialization : Note<
|
||||
"previous template specialization is here">;
|
||||
def err_explicit_instantiation_enum : Error<
|
||||
|
@ -2464,6 +2489,9 @@ def warn_typename_missing : ExtWarn<
|
|||
InGroup<DiagGroup<"typename-missing">>;
|
||||
def ext_typename_outside_of_template : ExtWarn<
|
||||
"'typename' occurs outside of a template">, InGroup<CXX11>;
|
||||
def warn_cxx98_compat_typename_outside_of_template : Warning<
|
||||
"use of 'typename' outside of a template is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_typename_refers_to_using_value_decl : Error<
|
||||
"typename specifier refers to a dependent using declaration for a value "
|
||||
"%0 in %1">;
|
||||
|
@ -2482,6 +2510,9 @@ def err_template_kw_missing : Error<
|
|||
"missing 'template' keyword prior to dependent template name '%0%1'">;
|
||||
def ext_template_outside_of_template : ExtWarn<
|
||||
"'template' keyword outside of a template">, InGroup<CXX11>;
|
||||
def warn_cxx98_compat_template_outside_of_template : Warning<
|
||||
"use of 'template' keyword outside of a template is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
|
||||
def err_non_type_template_in_nested_name_specifier : Error<
|
||||
"qualified name refers into a specialization of function template '%0'">;
|
||||
|
@ -3623,6 +3654,9 @@ def err_bad_const_cast_dest : Error<
|
|||
"which is not a reference, pointer-to-object, or pointer-to-data-member">;
|
||||
def ext_cast_fn_obj : Extension<
|
||||
"cast between pointer-to-function and pointer-to-object is an extension">;
|
||||
def warn_cxx98_compat_cast_fn_obj : Warning<
|
||||
"cast between pointer-to-function and pointer-to-object is incompatible with C++98">,
|
||||
InGroup<CXX98CompatPedantic>, DefaultIgnore;
|
||||
def err_bad_reinterpret_cast_small_int : Error<
|
||||
"cast from pointer to smaller type %2 loses information">;
|
||||
def err_bad_cxx_cast_vector_to_scalar_different_size : Error<
|
||||
|
@ -3708,6 +3742,10 @@ def ext_array_size_conversion : Extension<
|
|||
"implicit conversion from array size expression of type %0 to "
|
||||
"%select{integral|enumeration}1 type %2 is a C++11 extension">,
|
||||
InGroup<CXX11>;
|
||||
def warn_cxx98_compat_array_size_conversion : Warning<
|
||||
"implicit conversion from array size expression of type %0 to "
|
||||
"%select{integral|enumeration}1 type %2 is incompatible with C++98">,
|
||||
InGroup<CXX98CompatPedantic>, DefaultIgnore;
|
||||
def err_address_space_qualified_new : Error<
|
||||
"'new' cannot allocate objects of type %0 in address space '%1'">;
|
||||
def err_address_space_qualified_delete : Error<
|
||||
|
@ -4083,6 +4121,10 @@ def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
|
|||
"cannot pass object of %select{non-POD|non-trivial}0 type %1 through variadic"
|
||||
" %select{function|block|method|constructor}2; call will abort at runtime">,
|
||||
InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
|
||||
def warn_cxx98_compat_pass_non_pod_arg_to_vararg : Warning<
|
||||
"passing object of trivial but non-POD type %0 through variadic"
|
||||
" %select{function|block|method|constructor}1 is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
|
||||
def err_typecheck_call_invalid_ordered_compare : Error<
|
||||
"ordered compare requires two args of floating point type (%0 and %1)">;
|
||||
|
@ -4413,8 +4455,11 @@ def warn_not_compound_assign : Warning<
|
|||
"use of unary operator that may be intended as compound assignment (%0=)">;
|
||||
|
||||
// C++11 explicit conversion operators
|
||||
def warn_explicit_conversion_functions : Warning<
|
||||
def ext_explicit_conversion_functions : ExtWarn<
|
||||
"explicit conversion functions are a C++11 extension">, InGroup<CXX11>;
|
||||
def warn_cxx98_compat_explicit_conversion_functions : Warning<
|
||||
"explicit conversion functions are incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
|
||||
// C++11 defaulted functions
|
||||
def err_defaulted_default_ctor_params : Error<
|
||||
|
|
|
@ -1712,15 +1712,19 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
|
|||
// casting the return value of dlsym() and GetProcAddress().
|
||||
// FIXME: Conditionally-supported behavior should be configurable in the
|
||||
// TargetInfo or similar.
|
||||
if (!Self.getLangOptions().CPlusPlus0x)
|
||||
Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange;
|
||||
Self.Diag(OpRange.getBegin(),
|
||||
Self.getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
|
||||
<< OpRange;
|
||||
return TC_Success;
|
||||
}
|
||||
|
||||
if (DestType->isFunctionPointerType()) {
|
||||
// See above.
|
||||
if (!Self.getLangOptions().CPlusPlus0x)
|
||||
Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange;
|
||||
Self.Diag(OpRange.getBegin(),
|
||||
Self.getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
|
||||
<< OpRange;
|
||||
return TC_Success;
|
||||
}
|
||||
|
||||
|
|
|
@ -2127,8 +2127,9 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo,
|
|||
CXXRecordDecl *ClassDecl) {
|
||||
SourceLocation Loc = TInfo->getTypeLoc().getLocalSourceRange().getBegin();
|
||||
if (!LangOpts.CPlusPlus0x)
|
||||
return Diag(Loc, diag::err_delegation_0x_only)
|
||||
return Diag(Loc, diag::err_delegating_ctor)
|
||||
<< TInfo->getTypeLoc().getLocalSourceRange();
|
||||
Diag(Loc, diag::warn_cxx98_compat_delegating_ctor);
|
||||
|
||||
// Initialize the object.
|
||||
InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
|
||||
|
@ -5342,9 +5343,11 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
|
|||
R = Context.getFunctionType(ConvType, 0, 0, Proto->getExtProtoInfo());
|
||||
|
||||
// C++0x explicit conversion operators.
|
||||
if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x)
|
||||
if (D.getDeclSpec().isExplicitSpecified())
|
||||
Diag(D.getDeclSpec().getExplicitSpecLoc(),
|
||||
diag::warn_explicit_conversion_functions)
|
||||
getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_explicit_conversion_functions :
|
||||
diag::ext_explicit_conversion_functions)
|
||||
<< SourceRange(D.getDeclSpec().getExplicitSpecLoc());
|
||||
}
|
||||
|
||||
|
@ -5791,10 +5794,14 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S,
|
|||
case UnqualifiedId::IK_ConstructorName:
|
||||
case UnqualifiedId::IK_ConstructorTemplateId:
|
||||
// C++0x inherited constructors.
|
||||
Diag(Name.getSourceRange().getBegin(),
|
||||
getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_using_decl_constructor :
|
||||
diag::err_using_decl_constructor)
|
||||
<< SS.getRange();
|
||||
|
||||
if (getLangOptions().CPlusPlus0x) break;
|
||||
|
||||
Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_constructor)
|
||||
<< SS.getRange();
|
||||
return 0;
|
||||
|
||||
case UnqualifiedId::IK_DestructorName:
|
||||
|
@ -7432,7 +7439,7 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(
|
|||
&HasConstCopyAssignment);
|
||||
}
|
||||
|
||||
// In C++0x, the above citation has "or virtual added"
|
||||
// In C++11, the above citation has "or virtual" added
|
||||
if (LangOpts.CPlusPlus0x) {
|
||||
for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
|
||||
BaseEnd = ClassDecl->vbases_end();
|
||||
|
@ -9996,12 +10003,14 @@ Decl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
|
|||
|
||||
// C++ [class.friend]p1: A friend of a class is a function or
|
||||
// class that is not a member of the class . . .
|
||||
// C++0x changes this for both friend types and functions.
|
||||
// C++11 changes this for both friend types and functions.
|
||||
// Most C++ 98 compilers do seem to give an error here, so
|
||||
// we do, too.
|
||||
if (!Previous.empty() && DC->Equals(CurContext)
|
||||
&& !getLangOptions().CPlusPlus0x)
|
||||
Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
|
||||
if (!Previous.empty() && DC->Equals(CurContext))
|
||||
Diag(DS.getFriendSpecLoc(),
|
||||
getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_friend_is_member :
|
||||
diag::err_friend_is_member);
|
||||
|
||||
DCScope = getScopeForDeclContext(S, DC);
|
||||
|
||||
|
@ -10045,8 +10054,11 @@ Decl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
|
|||
|
||||
// C++ [class.friend]p1: A friend of a class is a function or
|
||||
// class that is not a member of the class . . .
|
||||
if (DC->Equals(CurContext) && !getLangOptions().CPlusPlus0x)
|
||||
Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
|
||||
if (DC->Equals(CurContext))
|
||||
Diag(DS.getFriendSpecLoc(),
|
||||
getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_friend_is_member :
|
||||
diag::err_friend_is_member);
|
||||
|
||||
if (D.isFunctionDefinition()) {
|
||||
// C++ [class.friend]p6:
|
||||
|
|
|
@ -562,8 +562,12 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
|
|||
if (CXXRecordDecl *Record = E->getType()->getAsCXXRecordDecl()) {
|
||||
if (Record->hasTrivialCopyConstructor() &&
|
||||
Record->hasTrivialMoveConstructor() &&
|
||||
Record->hasTrivialDestructor())
|
||||
Record->hasTrivialDestructor()) {
|
||||
DiagRuntimeBehavior(E->getLocStart(), 0,
|
||||
PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg)
|
||||
<< E->getType() << CT);
|
||||
TrivialEnough = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2643,9 +2647,10 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
|
|||
QualType Ty;
|
||||
|
||||
// long long is a C99 feature.
|
||||
if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x &&
|
||||
Literal.isLongLong)
|
||||
Diag(Tok.getLocation(), diag::ext_longlong);
|
||||
if (!getLangOptions().C99 && Literal.isLongLong)
|
||||
Diag(Tok.getLocation(),
|
||||
getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_longlong : diag::ext_longlong);
|
||||
|
||||
// Get the value in the widest-possible width.
|
||||
llvm::APInt ResultVal(Context.getTargetInfo().getIntMaxTWidth(), 0);
|
||||
|
|
|
@ -963,17 +963,18 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
|
|||
|
||||
QualType SizeType = ArraySize->getType();
|
||||
|
||||
ExprResult ConvertedSize
|
||||
= ConvertToIntegralOrEnumerationType(StartLoc, ArraySize,
|
||||
PDiag(diag::err_array_size_not_integral),
|
||||
PDiag(diag::err_array_size_incomplete_type)
|
||||
<< ArraySize->getSourceRange(),
|
||||
PDiag(diag::err_array_size_explicit_conversion),
|
||||
PDiag(diag::note_array_size_conversion),
|
||||
PDiag(diag::err_array_size_ambiguous_conversion),
|
||||
PDiag(diag::note_array_size_conversion),
|
||||
PDiag(getLangOptions().CPlusPlus0x? 0
|
||||
: diag::ext_array_size_conversion));
|
||||
ExprResult ConvertedSize = ConvertToIntegralOrEnumerationType(
|
||||
StartLoc, ArraySize,
|
||||
PDiag(diag::err_array_size_not_integral),
|
||||
PDiag(diag::err_array_size_incomplete_type)
|
||||
<< ArraySize->getSourceRange(),
|
||||
PDiag(diag::err_array_size_explicit_conversion),
|
||||
PDiag(diag::note_array_size_conversion),
|
||||
PDiag(diag::err_array_size_ambiguous_conversion),
|
||||
PDiag(diag::note_array_size_conversion),
|
||||
PDiag(getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_array_size_conversion :
|
||||
diag::ext_array_size_conversion));
|
||||
if (ConvertedSize.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
|
|
|
@ -1103,10 +1103,10 @@ static bool DiagnoseDefaultTemplateArgument(Sema &S,
|
|||
// template-argument, that declaration shall be a definition and shall be
|
||||
// the only declaration of the function template in the translation unit.
|
||||
// (C++98/03 doesn't have this wording; see DR226).
|
||||
if (!S.getLangOptions().CPlusPlus0x)
|
||||
S.Diag(ParamLoc,
|
||||
diag::ext_template_parameter_default_in_function_template)
|
||||
<< DefArgRange;
|
||||
S.Diag(ParamLoc, S.getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_template_parameter_default_in_function_template
|
||||
: diag::ext_template_parameter_default_in_function_template)
|
||||
<< DefArgRange;
|
||||
return false;
|
||||
|
||||
case Sema::TPC_ClassTemplateMember:
|
||||
|
@ -2268,9 +2268,11 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
|
|||
ParsedType ObjectType,
|
||||
bool EnteringContext,
|
||||
TemplateTy &Result) {
|
||||
if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() &&
|
||||
!getLangOptions().CPlusPlus0x)
|
||||
Diag(TemplateKWLoc, diag::ext_template_outside_of_template)
|
||||
if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent())
|
||||
Diag(TemplateKWLoc,
|
||||
getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_template_outside_of_template :
|
||||
diag::ext_template_outside_of_template)
|
||||
<< FixItHint::CreateRemoval(TemplateKWLoc);
|
||||
|
||||
DeclContext *LookupCtx = 0;
|
||||
|
@ -3261,13 +3263,19 @@ bool UnnamedLocalNoLinkageFinder::VisitAtomicType(const AtomicType* T) {
|
|||
|
||||
bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) {
|
||||
if (Tag->getDeclContext()->isFunctionOrMethod()) {
|
||||
S.Diag(SR.getBegin(), diag::ext_template_arg_local_type)
|
||||
S.Diag(SR.getBegin(),
|
||||
S.getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_template_arg_local_type :
|
||||
diag::ext_template_arg_local_type)
|
||||
<< S.Context.getTypeDeclType(Tag) << SR;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Tag->getDeclName() && !Tag->getTypedefNameForAnonDecl()) {
|
||||
S.Diag(SR.getBegin(), diag::ext_template_arg_unnamed_type) << SR;
|
||||
S.Diag(SR.getBegin(),
|
||||
S.getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_template_arg_unnamed_type :
|
||||
diag::ext_template_arg_unnamed_type) << SR;
|
||||
S.Diag(Tag->getLocation(), diag::note_template_unnamed_type_here);
|
||||
return true;
|
||||
}
|
||||
|
@ -3317,9 +3325,14 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
|
|||
// compounded from any of these types shall not be used as a
|
||||
// template-argument for a template type-parameter.
|
||||
//
|
||||
// C++0x allows these, and even in C++03 we allow them as an extension with
|
||||
// C++11 allows these, and even in C++03 we allow them as an extension with
|
||||
// a warning.
|
||||
if (!LangOpts.CPlusPlus0x && Arg->hasUnnamedOrLocalType()) {
|
||||
if (LangOpts.CPlusPlus0x ?
|
||||
Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_unnamed_type,
|
||||
SR.getBegin()) != DiagnosticsEngine::Ignored ||
|
||||
Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_local_type,
|
||||
SR.getBegin()) != DiagnosticsEngine::Ignored :
|
||||
Arg->hasUnnamedOrLocalType()) {
|
||||
UnnamedLocalNoLinkageFinder Finder(*this, SR);
|
||||
(void)Finder.Visit(Context.getCanonicalType(Arg));
|
||||
}
|
||||
|
@ -3358,9 +3371,11 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
|
|||
// See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
|
||||
bool ExtraParens = false;
|
||||
while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
|
||||
if (!Invalid && !ExtraParens && !S.getLangOptions().CPlusPlus0x) {
|
||||
if (!Invalid && !ExtraParens) {
|
||||
S.Diag(Arg->getSourceRange().getBegin(),
|
||||
diag::ext_template_arg_extra_parens)
|
||||
S.getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_template_arg_extra_parens :
|
||||
diag::ext_template_arg_extra_parens)
|
||||
<< Arg->getSourceRange();
|
||||
ExtraParens = true;
|
||||
}
|
||||
|
@ -3623,9 +3638,11 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg,
|
|||
// See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
|
||||
bool ExtraParens = false;
|
||||
while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
|
||||
if (!Invalid && !ExtraParens && !getLangOptions().CPlusPlus0x) {
|
||||
if (!Invalid && !ExtraParens) {
|
||||
Diag(Arg->getSourceRange().getBegin(),
|
||||
diag::ext_template_arg_extra_parens)
|
||||
getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_template_arg_extra_parens :
|
||||
diag::ext_template_arg_extra_parens)
|
||||
<< Arg->getSourceRange();
|
||||
ExtraParens = true;
|
||||
}
|
||||
|
@ -4571,24 +4588,28 @@ static bool CheckTemplateSpecializationScope(Sema &S,
|
|||
// C++0x [temp.expl.spec]p2:
|
||||
// An explicit specialization shall be declared in a namespace enclosing
|
||||
// the specialized template.
|
||||
if (!DC->InEnclosingNamespaceSetOf(SpecializedContext) &&
|
||||
!(S.getLangOptions().CPlusPlus0x && DC->Encloses(SpecializedContext))) {
|
||||
bool IsCPlusPlus0xExtension
|
||||
= !S.getLangOptions().CPlusPlus0x && DC->Encloses(SpecializedContext);
|
||||
if (isa<TranslationUnitDecl>(SpecializedContext))
|
||||
S.Diag(Loc, IsCPlusPlus0xExtension
|
||||
? diag::ext_template_spec_decl_out_of_scope_global
|
||||
: diag::err_template_spec_decl_out_of_scope_global)
|
||||
if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) {
|
||||
bool IsCPlusPlus0xExtension = DC->Encloses(SpecializedContext);
|
||||
if (isa<TranslationUnitDecl>(SpecializedContext)) {
|
||||
assert(!IsCPlusPlus0xExtension &&
|
||||
"DC encloses TU but isn't in enclosing namespace set");
|
||||
S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
|
||||
<< EntityKind << Specialized;
|
||||
else if (isa<NamespaceDecl>(SpecializedContext))
|
||||
S.Diag(Loc, IsCPlusPlus0xExtension
|
||||
? diag::ext_template_spec_decl_out_of_scope
|
||||
: diag::err_template_spec_decl_out_of_scope)
|
||||
<< EntityKind << Specialized
|
||||
<< cast<NamedDecl>(SpecializedContext);
|
||||
} else if (isa<NamespaceDecl>(SpecializedContext)) {
|
||||
int Diag;
|
||||
if (!IsCPlusPlus0xExtension)
|
||||
Diag = diag::err_template_spec_decl_out_of_scope;
|
||||
else if (!S.getLangOptions().CPlusPlus0x)
|
||||
Diag = diag::ext_template_spec_decl_out_of_scope;
|
||||
else
|
||||
Diag = diag::warn_cxx98_compat_template_spec_decl_out_of_scope;
|
||||
S.Diag(Loc, Diag)
|
||||
<< EntityKind << Specialized << cast<NamedDecl>(SpecializedContext);
|
||||
}
|
||||
|
||||
S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
|
||||
ComplainedAboutScope = true;
|
||||
ComplainedAboutScope =
|
||||
!(IsCPlusPlus0xExtension && S.getLangOptions().CPlusPlus0x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5333,12 +5354,12 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
|
|||
// In C++98/03 mode, we only give an extension warning here, because it
|
||||
// is not harmful to try to explicitly instantiate something that
|
||||
// has been explicitly specialized.
|
||||
if (!getLangOptions().CPlusPlus0x) {
|
||||
Diag(NewLoc, diag::ext_explicit_instantiation_after_specialization)
|
||||
<< PrevDecl;
|
||||
Diag(PrevDecl->getLocation(),
|
||||
diag::note_previous_template_specialization);
|
||||
}
|
||||
Diag(NewLoc, getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_explicit_instantiation_after_specialization :
|
||||
diag::ext_explicit_instantiation_after_specialization)
|
||||
<< PrevDecl;
|
||||
Diag(PrevDecl->getLocation(),
|
||||
diag::note_previous_template_specialization);
|
||||
HasNoEffect = true;
|
||||
return false;
|
||||
|
||||
|
@ -6413,9 +6434,11 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
|
|||
if (SS.isInvalid())
|
||||
return true;
|
||||
|
||||
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
|
||||
!getLangOptions().CPlusPlus0x)
|
||||
Diag(TypenameLoc, diag::ext_typename_outside_of_template)
|
||||
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
|
||||
Diag(TypenameLoc,
|
||||
getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_typename_outside_of_template :
|
||||
diag::ext_typename_outside_of_template)
|
||||
<< FixItHint::CreateRemoval(TypenameLoc);
|
||||
|
||||
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
|
||||
|
@ -6449,10 +6472,12 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
|
|||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgsIn,
|
||||
SourceLocation RAngleLoc) {
|
||||
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
|
||||
!getLangOptions().CPlusPlus0x)
|
||||
Diag(TypenameLoc, diag::ext_typename_outside_of_template)
|
||||
<< FixItHint::CreateRemoval(TypenameLoc);
|
||||
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
|
||||
Diag(TypenameLoc,
|
||||
getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_typename_outside_of_template :
|
||||
diag::ext_typename_outside_of_template)
|
||||
<< FixItHint::CreateRemoval(TypenameLoc);
|
||||
|
||||
// Translate the parser's template argument list in our AST format.
|
||||
TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
|
||||
|
|
|
@ -689,9 +689,10 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
|||
Result = Context.LongLongTy;
|
||||
|
||||
// long long is a C99 feature.
|
||||
if (!S.getLangOptions().C99 &&
|
||||
!S.getLangOptions().CPlusPlus0x)
|
||||
S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_longlong);
|
||||
if (!S.getLangOptions().C99)
|
||||
S.Diag(DS.getTypeSpecWidthLoc(),
|
||||
S.getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_longlong : diag::ext_longlong);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -703,9 +704,10 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
|||
Result = Context.UnsignedLongLongTy;
|
||||
|
||||
// long long is a C99 feature.
|
||||
if (!S.getLangOptions().C99 &&
|
||||
!S.getLangOptions().CPlusPlus0x)
|
||||
S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_longlong);
|
||||
if (!S.getLangOptions().C99)
|
||||
S.Diag(DS.getTypeSpecWidthLoc(),
|
||||
S.getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_longlong : diag::ext_longlong);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,3 +16,16 @@ VA_MACRO(,x) // expected-warning {{empty macro argument list is incompatible wit
|
|||
enum Enum {
|
||||
Enum_value, // expected-warning {{commas at the end of enumerator lists are incompatible with C++98}}
|
||||
};
|
||||
|
||||
template<typename T> struct InstantiationAfterSpecialization {};
|
||||
template<> struct InstantiationAfterSpecialization<int> {}; // expected-note {{here}}
|
||||
template struct InstantiationAfterSpecialization<int>; // expected-warning {{explicit instantiation of 'InstantiationAfterSpecialization<int>' that occurs after an explicit specialization is incompatible with C++98}}
|
||||
|
||||
void *dlsym();
|
||||
void (*FnPtr)() = (void(*)())dlsym(); // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}}
|
||||
void *FnVoidPtr = (void*)&dlsym; // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}}
|
||||
|
||||
struct ConvertToInt {
|
||||
operator int();
|
||||
};
|
||||
int *ArraySizeConversion = new int[ConvertToInt()]; // expected-warning {{implicit conversion from array size expression of type 'ConvertToInt' to integral type 'int' is incompatible with C++98}}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s
|
||||
|
||||
template<typename ...T> // expected-warning {{variadic templates are incompatible with C++98}}
|
||||
class Variadic1 {};
|
||||
|
@ -85,7 +86,7 @@ struct OverrideControl final : OverrideControlBase { // expected-warning {{'fina
|
|||
using AliasDecl = int; // expected-warning {{alias declarations are incompatible with C++98}}
|
||||
template<typename T> using AliasTemplate = T; // expected-warning {{alias declarations are incompatible with C++98}}
|
||||
|
||||
inline namespace N { // expected-warning {{inline namespaces are incompatible with C++98}}
|
||||
inline namespace InlineNS { // expected-warning {{inline namespaces are incompatible with C++98}}
|
||||
}
|
||||
|
||||
auto auto_deduction = 0; // expected-warning {{'auto' type specifier is incompatible with C++98}}
|
||||
|
@ -100,3 +101,62 @@ void no_except() noexcept; // expected-warning {{noexcept specifications are inc
|
|||
bool no_except_expr = noexcept(1 + 1); // expected-warning {{noexcept expressions are incompatible with C++98}}
|
||||
void *null = nullptr; // expected-warning {{'nullptr' is incompatible with C++98}}
|
||||
static_assert(true, "!"); // expected-warning {{static_assert declarations are incompatible with C++98}}
|
||||
|
||||
struct InhCtorBase {
|
||||
InhCtorBase(int);
|
||||
};
|
||||
struct InhCtorDerived : InhCtorBase {
|
||||
using InhCtorBase::InhCtorBase; // expected-warning {{inherited constructors are incompatible with C++98}}
|
||||
};
|
||||
|
||||
struct FriendMember {
|
||||
static void MemberFn();
|
||||
friend void FriendMember::MemberFn(); // expected-warning {{friend declaration naming a member of the declaring class is incompatible with C++98}}
|
||||
};
|
||||
|
||||
struct DelegCtor {
|
||||
DelegCtor(int) : DelegCtor() {} // expected-warning {{delegating constructors are incompatible with C++98}}
|
||||
DelegCtor();
|
||||
};
|
||||
|
||||
template<int n = 0> void DefaultFuncTemplateArg(); // expected-warning {{default template arguments for a function template are incompatible with C++98}}
|
||||
|
||||
template<typename T> int TemplateFn(T) { return 0; }
|
||||
void LocalTemplateArg() {
|
||||
struct S {};
|
||||
TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}}
|
||||
}
|
||||
struct {} obj_of_unnamed_type; // expected-note {{here}}
|
||||
int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning {{unnamed type as template argument is incompatible with C++98}}
|
||||
|
||||
namespace RedundantParensInAddressTemplateParam {
|
||||
int n;
|
||||
template<int*p> struct S {};
|
||||
S<(&n)> s; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}}
|
||||
S<(((&n)))> t; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}}
|
||||
}
|
||||
|
||||
namespace TemplateSpecOutOfScopeNs {
|
||||
template<typename T> struct S {}; // expected-note {{here}}
|
||||
}
|
||||
template<> struct TemplateSpecOutOfScopeNs::S<char> {}; // expected-warning {{class template specialization of 'S' outside namespace 'TemplateSpecOutOfScopeNs' is incompatible with C++98}}
|
||||
|
||||
struct Typename {
|
||||
template<typename T> struct Inner {};
|
||||
};
|
||||
typename ::Typename TypenameOutsideTemplate(); // expected-warning {{use of 'typename' outside of a template is incompatible with C++98}}
|
||||
Typename::template Inner<int> TemplateOutsideTemplate(); // expected-warning {{use of 'template' keyword outside of a template is incompatible with C++98}}
|
||||
|
||||
struct TrivialButNonPOD {
|
||||
int f(int);
|
||||
private:
|
||||
int k;
|
||||
};
|
||||
void Ellipsis(int n, ...);
|
||||
void TrivialButNonPODThroughEllipsis() {
|
||||
Ellipsis(1, TrivialButNonPOD()); // expected-warning {{passing object of trivial but non-POD type 'TrivialButNonPOD' through variadic function is incompatible with C++98}}
|
||||
}
|
||||
|
||||
struct HasExplicitConversion {
|
||||
explicit operator bool(); // expected-warning {{explicit conversion functions are incompatible with C++98}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue