diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-10-09 00:49:40 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-10-09 00:49:40 +0000 |
commit | 84ef9c64937dd5d6d2acde1af88220739d819e5f (patch) | |
tree | ddef7cd6f77172dec20eb4c087563b5d6d492c7f /clang/lib/Sema | |
parent | ad6690afa3e6e9bae6d8338016c4931e084ff380 (diff) | |
download | bcm5719-llvm-84ef9c64937dd5d6d2acde1af88220739d819e5f.tar.gz bcm5719-llvm-84ef9c64937dd5d6d2acde1af88220739d819e5f.zip |
[c++20] Implement most of P1152R4.
Diagnose some now-deprecated uses of volatile types:
* as function parameter types and return types
* as the type of a structured binding declaration
* as the type of the lvalue operand of an increment / decrement /
compound assignment operator
This does not implement a check for the deprecation of simple
assignments whose results are used; that check requires somewhat
more complexity and will be addressed separately.
llvm-svn: 374133
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 22 |
3 files changed, 50 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 98633981596..ff90b9548e2 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -775,6 +775,13 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D, return nullptr; } + // C++2a [dcl.struct.bind]p1: + // A cv that includes volatile is deprecated + if ((DS.getTypeQualifiers() & DeclSpec::TQ_volatile) && + getLangOpts().CPlusPlus2a) + Diag(DS.getVolatileSpecLoc(), + diag::warn_deprecated_volatile_structured_binding); + TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType R = TInfo->getType(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d158eaabde9..b691668da89 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11938,6 +11938,21 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, CheckForNullPointerDereference(*this, LHSExpr); + if (getLangOpts().CPlusPlus2a && LHSType.isVolatileQualified()) { + if (CompoundType.isNull()) { + // C++2a [expr.ass]p5: + // A simple-assignment whose left operand is of a volatile-qualified + // type is deprecated unless the assignment is either a discarded-value + // expression or an unevaluated operand + // FIXME: Implement checks for this. + } else { + // C++2a [expr.ass]p6: + // [Compound-assignment] expressions are deprecated if E1 has + // volatile-qualified type + Diag(Loc, diag::warn_deprecated_compound_assign_volatile) << LHSType; + } + } + // C99 6.5.16p3: The type of an assignment expression is the type of the // left operand unless the left operand has qualified type, in which case // it is the unqualified version of the type of the left operand. @@ -12126,6 +12141,12 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, // Now make sure the operand is a modifiable lvalue. if (CheckForModifiableLvalue(Op, OpLoc, S)) return QualType(); + if (S.getLangOpts().CPlusPlus2a && ResType.isVolatileQualified()) { + // C++2a [expr.pre.inc]p1, [expr.post.inc]p1: + // An operand with volatile-qualified type is deprecated + S.Diag(OpLoc, diag::warn_deprecated_increment_decrement_volatile) + << IsInc << ResType; + } // In C++, a prefix increment is the same type as the operand. Otherwise // (in C or with postfix), the increment is the unqualified type of the // operand. diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 87a672c5370..fccdb2bc2e2 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2475,6 +2475,11 @@ bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) { checkNonTrivialCUnion(T, Loc, NTCUC_FunctionReturn, NTCUK_Destruct|NTCUK_Copy); + // C++2a [dcl.fct]p12: + // A volatile-qualified return type is deprecated + if (T.isVolatileQualified() && getLangOpts().CPlusPlus2a) + Diag(Loc, diag::warn_deprecated_volatile_return) << T; + return false; } @@ -2555,6 +2560,11 @@ QualType Sema::BuildFunctionType(QualType T, Invalid = true; } + // C++2a [dcl.fct]p4: + // A parameter with volatile-qualified type is deprecated + if (ParamType.isVolatileQualified() && getLangOpts().CPlusPlus2a) + Diag(Loc, diag::warn_deprecated_volatile_param) << ParamType; + ParamTypes[Idx] = ParamType; } @@ -4685,6 +4695,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, S.Diag(DeclType.Loc, diag::err_func_returning_qualified_void) << T; } else diagnoseRedundantReturnTypeQualifiers(S, T, D, chunkIndex); + + // C++2a [dcl.fct]p12: + // A volatile-qualified return type is deprecated + if (T.isVolatileQualified() && S.getLangOpts().CPlusPlus2a) + S.Diag(DeclType.Loc, diag::warn_deprecated_volatile_return) << T; } // Objective-C ARC ownership qualifiers are ignored on the function @@ -5168,6 +5183,13 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, T->isObjectType()) T.addConst(); + // C++2a [dcl.fct]p4: + // A parameter with volatile-qualified type is deprecated + if (T.isVolatileQualified() && S.getLangOpts().CPlusPlus2a && + (D.getContext() == DeclaratorContext::PrototypeContext || + D.getContext() == DeclaratorContext::LambdaExprParameterContext)) + S.Diag(D.getIdentifierLoc(), diag::warn_deprecated_volatile_param) << T; + // If there was an ellipsis in the declarator, the declaration declares a // parameter pack whose type may be a pack expansion type. if (D.hasEllipsis()) { |