r374133 - [c++20] Implement most of P1152R4.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 8 17:49:40 PDT 2019


Author: rsmith
Date: Tue Oct  8 17:49:40 2019
New Revision: 374133

URL: http://llvm.org/viewvc/llvm-project?rev=374133&view=rev
Log:
[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.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaCXX/deprecated.cpp
    cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=374133&r1=374132&r2=374133&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Oct  8 17:49:40 2019
@@ -140,6 +140,7 @@ def DeprecatedImplementations :DiagGroup
 def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
 def DeprecatedRegister : DiagGroup<"deprecated-register">;
 def DeprecatedThisCapture : DiagGroup<"deprecated-this-capture">;
+def DeprecatedVolatile : DiagGroup<"deprecated-volatile">;
 def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
                                       [CXX11CompatDeprecatedWritableStr]>;
 // FIXME: Why is DeprecatedImplementations not in this group?
@@ -150,6 +151,7 @@ def Deprecated : DiagGroup<"deprecated",
                                           DeprecatedIncrementBool,
                                           DeprecatedRegister,
                                           DeprecatedThisCapture,
+                                          DeprecatedVolatile,
                                           DeprecatedWritableStr]>,
                  DiagCategory<"Deprecations">;
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=374133&r1=374132&r2=374133&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct  8 17:49:40 2019
@@ -6650,6 +6650,23 @@ def ext_increment_bool : ExtWarn<
   DefaultError, InGroup<IncrementBool>;
 def err_increment_decrement_enum : Error<
   "cannot %select{decrement|increment}0 expression of enum type %1">;
+
+def warn_deprecated_increment_decrement_volatile : Warning<
+  "%select{decrement|increment}0 of object of volatile-qualified type %1 "
+  "is deprecated">, InGroup<DeprecatedVolatile>;
+def warn_deprecated_compound_assign_volatile : Warning<
+  "compound assignment to object of volatile-qualified type %0 is deprecated">,
+  InGroup<DeprecatedVolatile>;
+def warn_deprecated_volatile_return : Warning<
+  "volatile-qualified return type %0 is deprecated">,
+  InGroup<DeprecatedVolatile>;
+def warn_deprecated_volatile_param : Warning<
+  "volatile-qualified parameter type %0 is deprecated">,
+  InGroup<DeprecatedVolatile>;
+def warn_deprecated_volatile_structured_binding : Warning<
+  "volatile qualifier in structured binding declaration is deprecated">,
+  InGroup<DeprecatedVolatile>;
+
 def err_catch_incomplete_ptr : Error<
   "cannot catch pointer to incomplete type %0">;
 def err_catch_incomplete_ref : Error<

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=374133&r1=374132&r2=374133&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Oct  8 17:49:40 2019
@@ -775,6 +775,13 @@ Sema::ActOnDecompositionDeclarator(Scope
       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();
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=374133&r1=374132&r2=374133&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Oct  8 17:49:40 2019
@@ -11938,6 +11938,21 @@ QualType Sema::CheckAssignmentOperands(E
 
   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 CheckIncrementDecrementO
   // 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.

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=374133&r1=374132&r2=374133&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Oct  8 17:49:40 2019
@@ -2475,6 +2475,11 @@ bool Sema::CheckFunctionReturnType(QualT
     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(QualTyp
       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 *GetFullTypeForDec
           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 *GetFullTypeForDec
       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()) {

Modified: cfe/trunk/test/SemaCXX/deprecated.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/deprecated.cpp?rev=374133&r1=374132&r2=374133&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/deprecated.cpp (original)
+++ cfe/trunk/test/SemaCXX/deprecated.cpp Tue Oct  8 17:49:40 2019
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -std=c++11 %s -Wdeprecated -verify -triple x86_64-linux-gnu
 // RUN: %clang_cc1 -std=c++14 %s -Wdeprecated -verify -triple x86_64-linux-gnu
 // RUN: %clang_cc1 -std=c++17 %s -Wdeprecated -verify -triple x86_64-linux-gnu
-// RUN: %clang_cc1 -std=c++2a %s -Wdeprecated -verify -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++2a %s -Wdeprecated -verify=expected,cxx20 -triple x86_64-linux-gnu
 
 // RUN: %clang_cc1 -std=c++14 %s -Wdeprecated -verify -triple x86_64-linux-gnu -Wno-deprecated-register -DNO_DEPRECATED_FLAGS
 
@@ -125,5 +125,72 @@ void array_index_comma() {
   X()[(X(), X())];
 }
 
+namespace DeprecatedVolatile {
+  volatile int n = 1;
+  void use(int);
+  void f() {
+    // simple assignments are deprecated only if their value is used
+    n = 5; // ok
+#if __cplusplus >= 201103L
+    decltype(n = 5) m = n; // ok expected-warning {{side effects}}
+    m = sizeof(n = 5); // ok expected-warning {{side effects}}
+#endif
+    (n = 5, 0); // ok
+    use(n = 5); // FIXME: deprecated
+    (n = 5); // FIXME: deprecated
+    int q = n = 5; // FIXME: deprecated
+    q = n = 5; // FIXME: deprecated
+#if __cplusplus >= 201103L
+    decltype(q = n = 5) m2 = q; // FIXME: deprecated expected-warning {{side effects}}
+#endif
+    q = sizeof(q = n = 5); // FIXME: deprecated expected-warning {{side effects}}
+
+    // inc / dec / compound assignments are always deprecated
+    ++n; // cxx20-warning {{increment of object of volatile-qualified type 'volatile int' is deprecated}}
+    --n; // cxx20-warning {{decrement of object of volatile-qualified type 'volatile int' is deprecated}}
+    n++; // cxx20-warning {{increment of object of volatile-qualified type 'volatile int' is deprecated}}
+    n--; // cxx20-warning {{decrement of object of volatile-qualified type 'volatile int' is deprecated}}
+    n += 5; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}}
+    n *= 3; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}}
+    n /= 2; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}}
+    n %= 42; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}}
+
+#if __cplusplus >= 201703L
+    struct X { int a, b; };
+    volatile auto [x, y] = X{1, 2}; // cxx20-warning {{volatile qualifier in structured binding declaration is deprecated}}
+
+    struct Y { volatile int a, b; };
+    auto [x2, y2] = Y{1, 2}; // ok
+#endif
+  }
+  volatile int g( // cxx20-warning {{volatile-qualified return type 'volatile int' is deprecated}}
+      volatile int n, // cxx20-warning {{volatile-qualified parameter type 'volatile int' is deprecated}}
+      volatile int (*p)( // cxx20-warning {{volatile-qualified return type 'volatile int' is deprecated}}
+        volatile int m) // cxx20-warning {{volatile-qualified parameter type 'volatile int' is deprecated}}
+      );
+#if __cplusplus >= 201103L
+  auto lambda = []( // cxx20-warning{{volatile-qualified return type 'volatile int' is deprecated}}
+      volatile int n) // cxx20-warning{{volatile-qualified parameter type 'volatile int' is deprecated}}
+    -> volatile int { return n; };
+#endif
+
+  template<typename T> T f(T v); // cxx20-warning 2{{deprecated}}
+  int use_f = f<volatile int>(0); // FIXME: Missing "in instantiation of" note.
+
+  // OK, only the built-in operators are deprecated.
+  struct UDT {
+    UDT(volatile const UDT&);
+    UDT &operator=(const UDT&);
+    UDT &operator=(const UDT&) volatile;
+    UDT operator+=(const UDT&) volatile;
+  };
+  void h(UDT a) {
+    volatile UDT b = a;
+    volatile UDT c = b;
+    a = c = a;
+    b += a;
+  }
+}
+
 # 1 "/usr/include/system-header.h" 1 3
 void system_header_function(void) throw();

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=374133&r1=374132&r2=374133&view=diff
==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Tue Oct  8 17:49:40 2019
@@ -1103,7 +1103,7 @@ as the draft C++2a standard evolves.
     <tr>
       <td>Deprecate some problematic uses of <tt>volatile</tt></td>
       <td><a href="http://wg21.link/p1152r4">P1152R4</a></td>
-      <td class="none" align="center">No</td>
+      <td class="partial" align="center">Partial</td>
     </tr>
     <tr>
       <td><tt>[[nodiscard("with reason")]]</tt></td>




More information about the cfe-commits mailing list