From: Marek Polacek Date: Thu, 29 Aug 2019 03:11:50 +0000 (+0000) Subject: Implement P1152R4: Deprecating some uses of volatile. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8a902edbbdb53a00209e88b6182457941ff196a9;p=gcc.git Implement P1152R4: Deprecating some uses of volatile. PR c++/91361 * c-opts.c (c_common_post_options): Enable -Wvolatile by default for C++2a, unless -Wno-deprecated. * c.opt (Wvolatile): New warning. * cp-gimplify.c (cp_fold): Set TREE_THIS_VOLATILE. * decl.c (grokdeclarator): Warn about a volatile-qualified structured binding and return type. (grokparms): Warn about a volatile-qualified function parameter. * expr.c (mark_use) : Emit a -Wvolatile warning. * typeck.c (cp_build_unary_op): Emit a -Wvolatile warning for pre and post ++/-- on a volatile operand. (genericize_compound_lvalue): Use a better location. Don't lose TREE_THIS_VOLATILE. (cp_build_modify_expr): Emit a -Wvolatile warning for a compound assignment whose LHS is volatile-qualified. Build the assignment with a more precise location. * doc/invoke.texi: Document -Wvolatile. * c-c++-common/Wbool-operation-1.c: Use -Wno-volatile in C++. * c-c++-common/gomp/atomic-1.c: Likewise. * c-c++-common/gomp/atomic-9.c: Likewise. * c-c++-common/gomp/depend-iterator-1.c: Likewise. * c-c++-common/gomp/loop-1.c: Adjust warning location for C++. * c-c++-common/gomp/order-3.c: Likewise. * c-c++-common/pr69733.c: Use -Wno-volatile in C++. * c-c++-common/spec-barrier-2.c: Likewise. * c-c++-common/tm/pr54893.c: Likewise. * g++.dg/cpp0x/pr65327.C: Add dg-warning. * g++.dg/cpp0x/rv-conv2.C: Likewise. * g++.dg/cpp0x/rv1n.C: Likewise. * g++.dg/cpp0x/rv1p.C: Likewise. * g++.dg/cpp0x/rv2n.C: Likewise. * g++.dg/cpp0x/rv2p.C: Likewise. * g++.dg/cpp0x/rv3n.C: Likewise. * g++.dg/cpp0x/rv3p.C: Likewise. * g++.dg/cpp0x/rv4n.C: Likewise. * g++.dg/cpp0x/rv4p.C: Likewise. * g++.dg/cpp0x/rv5n.C: Likewise. * g++.dg/cpp0x/rv5p.C: Likewise. * g++.dg/cpp0x/rv6n.C: Likewise. * g++.dg/cpp0x/rv6p.C: Likewise. * g++.dg/cpp0x/rv7n.C: Likewise. * g++.dg/cpp0x/rv7p.C: Likewise. * g++.dg/cpp0x/rv8p.C: Likewise. * g++.dg/cpp0x/trailing14.C: Use -Wno-volatile. * g++.dg/cpp1y/new1.C: Add dg-warning. * g++.dg/cpp2a/volatile1.C: New test. * g++.dg/cpp2a/volatile2.C: New test. * g++.dg/cpp2a/volatile3.C: New test. * g++.dg/cpp2a/volatile4.C: New test. * g++.dg/expr/bool3.C: Add dg-warning. * g++.dg/expr/bool4.C: Likewise. * g++.dg/expr/cond9.C: Likewise. * g++.dg/ext/vector25.C: Likewise. * g++.dg/gomp/depend-iterator-1.C: Use -Wno-volatile. * g++.dg/inherit/covariant21.C: Add dg-warning. * g++.dg/init/ref18.C: Likewise. * g++.dg/ipa/pr63838.C: Likewise. * g++.dg/overload/rvalue2.C: Likewise. * g++.dg/parse/semicolon4.C: Likewise. * g++.dg/warn/Wreturn-type-4.C: Likewise. * g++.dg/warn/pr36069.C: Likewise. * g++.old-deja/g++.mike/p9506.C: Likewise. * g++.old-deja/g++.other/volatile1.C: Likewise. From-SVN: r275022 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8b5ccd2f98d..c4a7b30ead8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-28 Marek Polacek + + Implement P1152R4: Deprecating some uses of volatile. + PR c++/91361 + * doc/invoke.texi: Document -Wvolatile. + 2019-08-28 Marek Polacek PR c++/91360 - Implement C++20 P1143R2: constinit. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index d0a19e3870d..8b4e75cb78e 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2019-08-28 Marek Polacek + + Implement P1152R4: Deprecating some uses of volatile. + PR c++/91361 + * c-opts.c (c_common_post_options): Enable -Wvolatile by + default for C++2a, unless -Wno-deprecated. + * c.opt (Wvolatile): New warning. + 2019-08-28 Marek Polacek PR c++/91360 - Implement C++20 P1143R2: constinit. diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index da783e4990c..fa8cd0ccb09 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -919,6 +919,10 @@ c_common_post_options (const char **pfilename) if (!global_options_set.x_warn_comma_subscript) warn_comma_subscript = (cxx_dialect >= cxx2a && warn_deprecated); + /* -Wvolatile is enabled by default in C++20. */ + if (!global_options_set.x_warn_volatile) + warn_volatile = (cxx_dialect >= cxx2a && warn_deprecated); + /* Declone C++ 'structors if -Os. */ if (flag_declone_ctor_dtor == -1) flag_declone_ctor_dtor = optimize_size; diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 4c468d0f6c2..f8a1a1dbdad 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1228,6 +1228,10 @@ Wno-vla-larger-than C ObjC C++ LTO ObjC++ Alias(Wvla-larger-than=,18446744073709551615EiB,none) Warning -Wno-vla-larger-than Disable Wvla-larger-than= warning. Equivalent to Wvla-larger-than= or larger. +Wvolatile +C++ ObjC++ Var(warn_volatile) Warning +Warn about deprecated uses of volatile qualifier. + Wvolatile-register-var C ObjC C++ ObjC++ Var(warn_volatile_register_var) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn when a register variable is declared volatile. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2e7c26cd447..818d32b29d3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2019-08-28 Marek Polacek + + Implement P1152R4: Deprecating some uses of volatile. + PR c++/91361 + * cp-gimplify.c (cp_fold): Set TREE_THIS_VOLATILE. + * decl.c (grokdeclarator): Warn about a volatile-qualified structured + binding and return type. + (grokparms): Warn about a volatile-qualified function parameter. + * expr.c (mark_use) : Emit a -Wvolatile warning. + * typeck.c (cp_build_unary_op): Emit a -Wvolatile warning for pre and + post ++/-- on a volatile operand. + (genericize_compound_lvalue): Use a better location. Don't lose + TREE_THIS_VOLATILE. + (cp_build_modify_expr): Emit a -Wvolatile warning for a compound + assignment whose LHS is volatile-qualified. Build the assignment with + a more precise location. + 2019-08-28 Marek Polacek PR c++/91360 - Implement C++20 P1143R2: constinit. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 065dcb7ba06..49fa47ac3af 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -2507,6 +2507,9 @@ cp_fold (tree x) else x = org_x; } + if (code == MODIFY_EXPR && TREE_CODE (x) == MODIFY_EXPR) + TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x); + break; case VEC_COND_EXPR: diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c5cc22a8d6d..2aef330455f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11233,6 +11233,10 @@ grokdeclarator (const cp_declarator *declarator, if (concept_p) error_at (declspecs->locations[ds_concept], "structured binding declaration cannot be %qs", "concept"); + /* [dcl.struct.bind] "A cv that includes volatile is deprecated." */ + if (type_quals & TYPE_QUAL_VOLATILE) + warning_at (declspecs->locations[ds_volatile], OPT_Wvolatile, + "%-qualified structured binding is deprecated"); switch (storage_class) { case sc_none: @@ -11623,6 +11627,13 @@ grokdeclarator (const cp_declarator *declarator, if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type)) warning_at (typespec_loc, OPT_Wignored_qualifiers, "type " "qualifiers ignored on function return type"); + /* [dcl.fct] "A volatile-qualified return type is + deprecated." */ + if (type_quals & TYPE_QUAL_VOLATILE) + warning_at (typespec_loc, OPT_Wvolatile, + "%-qualified return type is " + "deprecated"); + /* We now know that the TYPE_QUALS don't apply to the decl, but to its return type. */ type_quals = TYPE_UNQUALIFIED; @@ -13378,6 +13389,13 @@ grokparms (tree parmlist, tree *parms) cp_warn_deprecated_use (deptype); } + /* [dcl.fct] "A parameter with volatile-qualified type is + deprecated." */ + if (CP_TYPE_VOLATILE_P (type)) + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wvolatile, + "%-qualified parameter is " + "deprecated"); + /* Top-level qualifiers on the parameters are ignored for function types. */ type = cp_build_qualified_type (type, 0); diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 9160043ed11..212a7f93c5a 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -207,6 +207,28 @@ mark_use (tree expr, bool rvalue_p, bool read_p, recurse_op[0] = true; break; + case MODIFY_EXPR: + { + tree lhs = TREE_OPERAND (expr, 0); + /* [expr.ass] "A simple assignment whose left operand is of + a volatile-qualified type is deprecated unless the assignment + is either a discarded-value expression or appears in an + unevaluated context." */ + if (read_p + && !cp_unevaluated_operand + && (TREE_THIS_VOLATILE (lhs) + || CP_TYPE_VOLATILE_P (TREE_TYPE (lhs))) + && !TREE_THIS_VOLATILE (expr)) + { + warning_at (location_of (expr), OPT_Wvolatile, + "using value of simple assignment with %-" + "qualified left operand is deprecated"); + /* Make sure not to warn about this assignment again. */ + TREE_THIS_VOLATILE (expr) = true; + } + break; + } + default: break; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c09bb309142..d4f2d98143b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6459,6 +6459,17 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert, complain)) return error_mark_node; + /* [depr.volatile.type] "Postfix ++ and -- expressions and + prefix ++ and -- expressions of volatile-qualified arithmetic + and pointer types are deprecated." */ + if (TREE_THIS_VOLATILE (arg) || CP_TYPE_VOLATILE_P (TREE_TYPE (arg))) + warning_at (location, OPT_Wvolatile, + "%qs expression of %-qualified type is " + "deprecated", + ((code == PREINCREMENT_EXPR + || code == POSTINCREMENT_EXPR) + ? "++" : "--")); + /* Forbid using -- or ++ in C++17 on `bool'. */ if (TREE_CODE (declared_type) == BOOLEAN_TYPE) { @@ -8278,6 +8289,15 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype))) || MAYBE_CLASS_TYPE_P (lhstype))); + /* An expression of the form E1 op= E2. [expr.ass] says: + "Such expressions are deprecated if E1 has volatile-qualified + type." We warn here rather than in cp_genericize_r because + for compound assignments we are supposed to warn even if the + assignment is a discarded-value expression. */ + if (TREE_THIS_VOLATILE (lhs) || CP_TYPE_VOLATILE_P (lhstype)) + warning_at (loc, OPT_Wvolatile, + "compound assignment with %-qualified left " + "operand is deprecated"); /* Preevaluate the RHS to make sure its evaluation is complete before the lvalue-to-rvalue conversion of the LHS: @@ -8450,8 +8470,8 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, goto ret; } - result = build2 (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR, - lhstype, lhs, newrhs); + result = build2_loc (loc, modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR, + lhstype, lhs, newrhs); TREE_SIDE_EFFECTS (result) = 1; if (!plain_assign) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 1391a562c35..aa9886ee09f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -243,7 +243,7 @@ in the following sections. -Wno-non-template-friend -Wold-style-cast @gol -Woverloaded-virtual -Wno-pmf-conversions @gol -Wno-class-conversion -Wno-terminate @gol --Wsign-promo -Wvirtual-inheritance} +-Wsign-promo -Wvirtual-inheritance -Wvolatile} @item Objective-C and Objective-C++ Language Options @xref{Objective-C and Objective-C++ Dialect Options,,Options Controlling @@ -3516,6 +3516,19 @@ result in a call to @code{terminate}. Disable the warning about the case when a conversion function converts an object to the same type, to a base class of that type, or to void; such a conversion function will never be called. + +@item -Wvolatile @r{(C++ and Objective-C++ only)} +@opindex Wvolatile +@opindex Wno-volatile +Warn about deprecated uses of the volatile qualifier. This includes postfix +and prefix @code{++} and @code{--} expressions of volatile-qualified types, +using simple assignments where the left operand is a volatile-qualified +non-class type for their value, compound assignments where the left operand +is a volatile-qualified non-class type, volatile-qualified function return +type, volatile-qualified parameter type, and structured bindings of a +volatile-qualified type. This usage was deprecated in C++20. + +Enabled by default with @option{-std=c++2a}. @end table @node Objective-C and Objective-C++ Dialect Options diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bd9fe70d084..3a503ac8b3d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,7 +1,58 @@ +2019-08-28 Marek Polacek + + Implement P1152R4: Deprecating some uses of volatile. + PR c++/91361 + * c-c++-common/Wbool-operation-1.c: Use -Wno-volatile in C++. + * c-c++-common/gomp/atomic-1.c: Likewise. + * c-c++-common/gomp/atomic-9.c: Likewise. + * c-c++-common/gomp/depend-iterator-1.c: Likewise. + * c-c++-common/gomp/loop-1.c: Adjust warning location for C++. + * c-c++-common/gomp/order-3.c: Likewise. + * c-c++-common/pr69733.c: Use -Wno-volatile in C++. + * c-c++-common/spec-barrier-2.c: Likewise. + * c-c++-common/tm/pr54893.c: Likewise. + * g++.dg/cpp0x/pr65327.C: Add dg-warning. + * g++.dg/cpp0x/rv-conv2.C: Likewise. + * g++.dg/cpp0x/rv1n.C: Likewise. + * g++.dg/cpp0x/rv1p.C: Likewise. + * g++.dg/cpp0x/rv2n.C: Likewise. + * g++.dg/cpp0x/rv2p.C: Likewise. + * g++.dg/cpp0x/rv3n.C: Likewise. + * g++.dg/cpp0x/rv3p.C: Likewise. + * g++.dg/cpp0x/rv4n.C: Likewise. + * g++.dg/cpp0x/rv4p.C: Likewise. + * g++.dg/cpp0x/rv5n.C: Likewise. + * g++.dg/cpp0x/rv5p.C: Likewise. + * g++.dg/cpp0x/rv6n.C: Likewise. + * g++.dg/cpp0x/rv6p.C: Likewise. + * g++.dg/cpp0x/rv7n.C: Likewise. + * g++.dg/cpp0x/rv7p.C: Likewise. + * g++.dg/cpp0x/rv8p.C: Likewise. + * g++.dg/cpp0x/trailing14.C: Use -Wno-volatile. + * g++.dg/cpp1y/new1.C: Add dg-warning. + * g++.dg/cpp2a/volatile1.C: New test. + * g++.dg/cpp2a/volatile2.C: New test. + * g++.dg/cpp2a/volatile3.C: New test. + * g++.dg/cpp2a/volatile4.C: New test. + * g++.dg/expr/bool3.C: Add dg-warning. + * g++.dg/expr/bool4.C: Likewise. + * g++.dg/expr/cond9.C: Likewise. + * g++.dg/ext/vector25.C: Likewise. + * g++.dg/gomp/depend-iterator-1.C: Use -Wno-volatile. + * g++.dg/inherit/covariant21.C: Add dg-warning. + * g++.dg/init/ref18.C: Likewise. + * g++.dg/ipa/pr63838.C: Likewise. + * g++.dg/overload/rvalue2.C: Likewise. + * g++.dg/parse/semicolon4.C: Likewise. + * g++.dg/warn/Wreturn-type-4.C: Likewise. + * g++.dg/warn/pr36069.C: Likewise. + * g++.old-deja/g++.mike/p9506.C: Likewise. + * g++.old-deja/g++.other/volatile1.C: Likewise. + 2019-08-28 Steven G. Kargl PR fortran/91551 - * gfortran.dg/allocated_3.f90 + * gfortran.dg/allocated_3.f90 2019-08-28 Marek Polacek diff --git a/gcc/testsuite/c-c++-common/Wbool-operation-1.c b/gcc/testsuite/c-c++-common/Wbool-operation-1.c index 04891878155..ce87705692a 100644 --- a/gcc/testsuite/c-c++-common/Wbool-operation-1.c +++ b/gcc/testsuite/c-c++-common/Wbool-operation-1.c @@ -1,6 +1,7 @@ /* PR c/77490 */ /* { dg-do compile } */ /* { dg-options "-Wall -Wno-psabi" } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ #ifndef __cplusplus # define bool _Bool diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-1.c b/gcc/testsuite/c-c++-common/gomp/atomic-1.c index 3e4bc569ba7..1facf4586f5 100644 --- a/gcc/testsuite/c-c++-common/gomp/atomic-1.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-1.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ int x; volatile int y; diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-9.c b/gcc/testsuite/c-c++-common/gomp/atomic-9.c index c07da8fc712..35548395f36 100644 --- a/gcc/testsuite/c-c++-common/gomp/atomic-9.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-9.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-fopenmp -fdump-tree-ompexp" } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ /* { dg-require-effective-target cas_int } */ volatile int *bar(void); diff --git a/gcc/testsuite/c-c++-common/gomp/depend-iterator-1.c b/gcc/testsuite/c-c++-common/gomp/depend-iterator-1.c index 4fb01c174ec..6fa60215f43 100644 --- a/gcc/testsuite/c-c++-common/gomp/depend-iterator-1.c +++ b/gcc/testsuite/c-c++-common/gomp/depend-iterator-1.c @@ -1,3 +1,5 @@ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ + int arr[64], arr2[64]; struct S { int a[4]; } k; short arr4[4]; diff --git a/gcc/testsuite/c-c++-common/gomp/loop-1.c b/gcc/testsuite/c-c++-common/gomp/loop-1.c index d2f943aea54..4fb995c02a7 100644 --- a/gcc/testsuite/c-c++-common/gomp/loop-1.c +++ b/gcc/testsuite/c-c++-common/gomp/loop-1.c @@ -100,8 +100,8 @@ f4 (int *a) #pragma omp loop order(concurrent) bind(parallel) for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c } } */ } #pragma omp loop order(concurrent) bind(parallel) for (i = 0; i < 64; i++) @@ -172,8 +172,8 @@ f5 (int *a) #pragma omp loop for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c } } */ } #pragma omp loop for (i = 0; i < 64; i++) @@ -245,8 +245,8 @@ f6 (int *a) #pragma omp loop for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c } } */ } #pragma omp loop for (i = 0; i < 64; i++) diff --git a/gcc/testsuite/c-c++-common/gomp/order-3.c b/gcc/testsuite/c-c++-common/gomp/order-3.c index 2d51bf37749..e33386dd5cc 100644 --- a/gcc/testsuite/c-c++-common/gomp/order-3.c +++ b/gcc/testsuite/c-c++-common/gomp/order-3.c @@ -50,8 +50,8 @@ f1 (int *a) #pragma omp simd order(concurrent) for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c } } */ } #pragma omp simd order(concurrent) for (i = 0; i < 64; i++) @@ -112,8 +112,8 @@ f2 (int *a) #pragma omp for simd order(concurrent) for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c } } */ } #pragma omp for simd order(concurrent) for (i = 0; i < 64; i++) @@ -174,8 +174,8 @@ f3 (int *a) #pragma omp for order(concurrent) for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c } } */ } #pragma omp for order(concurrent) for (i = 0; i < 64; i++) diff --git a/gcc/testsuite/c-c++-common/pr69733.c b/gcc/testsuite/c-c++-common/pr69733.c index 57ec1eccb9f..ab70f49009c 100644 --- a/gcc/testsuite/c-c++-common/pr69733.c +++ b/gcc/testsuite/c-c++-common/pr69733.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-W -fdiagnostics-show-caret" } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ typedef const double cd; double val; @@ -21,4 +22,3 @@ cd val2() {return val;} /* { dg-warning "qualifiers ignored" } */ cd val2() {return val;} ^~ { dg-end-multiline-output "" } */ - diff --git a/gcc/testsuite/c-c++-common/spec-barrier-2.c b/gcc/testsuite/c-c++-common/spec-barrier-2.c index b09567e62a9..a27ec54f0d3 100644 --- a/gcc/testsuite/c-c++-common/spec-barrier-2.c +++ b/gcc/testsuite/c-c++-common/spec-barrier-2.c @@ -1,4 +1,5 @@ /* { dg-do run } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ /* Even on targets that don't need the optional failval parameter, side-effects on the operand should still be calculated. */ diff --git a/gcc/testsuite/c-c++-common/tm/pr54893.c b/gcc/testsuite/c-c++-common/tm/pr54893.c index 3766078d31e..266cbe9c652 100644 --- a/gcc/testsuite/c-c++-common/tm/pr54893.c +++ b/gcc/testsuite/c-c++-common/tm/pr54893.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-fgnu-tm -fdump-ipa-tmipa" } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ /* Test that volatiles are allowed inside relaxed transactions. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/pr65327.C b/gcc/testsuite/g++.dg/cpp0x/pr65327.C index 5176b3c3204..6e888ebff2c 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr65327.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr65327.C @@ -11,7 +11,7 @@ foo () static constexpr volatile int k = 5; } -constexpr volatile int +constexpr volatile int // { dg-warning "deprecated" "" { target c++2a } } bar () { return i; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-conv2.C b/gcc/testsuite/g++.dg/cpp0x/rv-conv2.C index 9b9b154995b..2f2a1fa702a 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv-conv2.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv-conv2.C @@ -1,16 +1,16 @@ // PR c++/89705 // { dg-do compile { target c++11 } } -struct W { operator const volatile int(); }; +struct W { operator const volatile int(); }; // { dg-warning "deprecated" "" { target c++2a } } const int& rci = W(); struct X { operator const int(); }; int&& rri = X(); -struct Y { operator volatile int(); }; +struct Y { operator volatile int(); }; // { dg-warning "deprecated" "" { target c++2a } } int&& rri2 = Y(); -struct Z { operator const volatile int(); }; +struct Z { operator const volatile int(); }; // { dg-warning "deprecated" "" { target c++2a } } volatile int&& rri3 = Z(); enum E { A }; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv1n.C b/gcc/testsuite/g++.dg/cpp0x/rv1n.C index f5e75681758..a762fc85862 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv1n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv1n.C @@ -26,8 +26,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 1 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv1p.C b/gcc/testsuite/g++.dg/cpp0x/rv1p.C index a9097276d5a..e2a983a7708 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv1p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv1p.C @@ -26,8 +26,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 1 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv2n.C b/gcc/testsuite/g++.dg/cpp0x/rv2n.C index 65eda80fba0..2871ccf9ab3 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv2n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv2n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 2 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv2p.C b/gcc/testsuite/g++.dg/cpp0x/rv2p.C index 25a42ba2af8..bab0dce3d97 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv2p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv2p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 2 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv3n.C b/gcc/testsuite/g++.dg/cpp0x/rv3n.C index 4549438f8ef..35cdba95858 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv3n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv3n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 3 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv3p.C b/gcc/testsuite/g++.dg/cpp0x/rv3p.C index 2d7d78df6be..b25aa26c9b0 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv3p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv3p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 3 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv4n.C b/gcc/testsuite/g++.dg/cpp0x/rv4n.C index 29deb3fc81b..6941a13de6c 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv4n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv4n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 4 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv4p.C b/gcc/testsuite/g++.dg/cpp0x/rv4p.C index 0e4903bc291..cd0d631d780 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv4p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv4p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 4 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv5n.C b/gcc/testsuite/g++.dg/cpp0x/rv5n.C index f11d07a3921..086aa460c68 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv5n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv5n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 5 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv5p.C b/gcc/testsuite/g++.dg/cpp0x/rv5p.C index 63441a3f0da..34c1017f578 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv5p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv5p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 5 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv6n.C b/gcc/testsuite/g++.dg/cpp0x/rv6n.C index 0ebbe33e1d1..b21d22a5b87 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv6n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv6n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 6 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv6p.C b/gcc/testsuite/g++.dg/cpp0x/rv6p.C index 26714f0c9aa..fee692bb08f 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv6p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv6p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 6 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv7n.C b/gcc/testsuite/g++.dg/cpp0x/rv7n.C index d9e371b8adb..5bc313cc07f 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv7n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv7n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 7 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv7p.C b/gcc/testsuite/g++.dg/cpp0x/rv7p.C index 60a35835c7d..b0b8f965498 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv7p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv7p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 7 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv8p.C b/gcc/testsuite/g++.dg/cpp0x/rv8p.C index e12da4b8d79..287fb93b432 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv8p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv8p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 8 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing14.C b/gcc/testsuite/g++.dg/cpp0x/trailing14.C index 2544d0bab5e..4ebb37406ad 100644 --- a/gcc/testsuite/g++.dg/cpp0x/trailing14.C +++ b/gcc/testsuite/g++.dg/cpp0x/trailing14.C @@ -1,6 +1,6 @@ // PR c++/65775 // { dg-do compile { target c++11 } } -// { dg-options "-Wignored-qualifiers" } +// { dg-options "-Wignored-qualifiers -Wno-volatile" } using Qi = int const volatile; Qi q1(); // { dg-warning "1: type qualifiers ignored" } diff --git a/gcc/testsuite/g++.dg/cpp1y/new1.C b/gcc/testsuite/g++.dg/cpp1y/new1.C index 5e4f1bf6b0b..b9ad64dfcc0 100644 --- a/gcc/testsuite/g++.dg/cpp1y/new1.C +++ b/gcc/testsuite/g++.dg/cpp1y/new1.C @@ -65,7 +65,7 @@ void test_unused() { volatile double d = 0.0; double *p = new double (); - d += 1.0; + d += 1.0; // { dg-warning "deprecated" "" { target c++2a } } delete p; } diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile1.C b/gcc/testsuite/g++.dg/cpp2a/volatile1.C new file mode 100644 index 00000000000..e47591b13bc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/volatile1.C @@ -0,0 +1,141 @@ +// PR c++/91361 - P1152R4: Deprecating some uses of volatile. +// { dg-do compile { target c++17 } } + +#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x)) + +struct S { + volatile int a : 4; + int b : 2; +}; + +struct T { + int a : 4; + int b : 2; +}; + +union U { + char c; + int i; +}; + +struct W { + W(); + W(volatile W&); + W& operator=(volatile W&) volatile; +}; + +volatile int // { dg-warning ".volatile.-qualified return type is deprecated" "" { target c++2a } } +fn (volatile int i) // { dg-warning ".volatile.-qualified parameter is deprecated" "" { target c++2a } } +{ + volatile int v = 10; + int *volatile p = nullptr; + + // Pre/post ++/--. + v++; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + ++v; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + v--; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + --v; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + p++; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + ++p; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + p--; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + --p; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + return v + i + *p; +} + +void +fn2 () +{ + volatile int vi = 42; + int i = 24; + + // Discarded-value expression ([expr.context]). + // The lvalue-to-rvalue conversion is applied here: + vi; + // ...but not here. Otherwise we'd write to VI and then immediately read it. + vi = 42; + vi = i; + vi = i = 42; + i = vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + &(vi = i); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + (vi = 42, 45); + (i = vi = 42, 10); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + i = vi; // LHS not volatile. + i = (vi = i, 42); + static_cast(vi = i); + static_cast(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + (void)(vi = i); + (void)(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + // Unevaluated operand. + decltype(vi = 42) x = vi; + decltype(i = vi = 42) x3 = i; + + // Compound assignments. + vi += i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi -= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi %= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi ^= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi |= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi /= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi = vi += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi += vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + i *= vi; + decltype(vi -= 42) x2 = vi; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + // Structured bindings. + int a[] = { 10, 5 }; + const auto & [cxr, cyr] = a; + const volatile auto & [cvxr, cvyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" "" { target c++2a } } + volatile auto & [vxr, vyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" "" { target c++2a } } +} + +void +fn3 () +{ + volatile int i, j, k = 0; + i = j = k; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + ACCESS_ONCE(j); + + S s; + s.b = 1; + + volatile U u; + u.c = 42; + i = u.c = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + u.c += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + volatile T t; + t.a = 3; + j = t.a = 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + t.a += 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + volatile int *src = &i; + *src; // No assignment, don't warn. +} + +void +fn4 () +{ + volatile W vw; + W w; + // Assignment to objects of a class is defined by the copy/move assignment + // operator. + vw = w; + w = vw; +} + +template +void raccoon () +{ + volatile T t, u; + t = 42; + u = t = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + t &= 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } +} + +void +fn5 () +{ + raccoon(); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile2.C b/gcc/testsuite/g++.dg/cpp2a/volatile2.C new file mode 100644 index 00000000000..1a7889a6a8c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/volatile2.C @@ -0,0 +1,142 @@ +// PR c++/91361 - P1152R4: Deprecating some uses of volatile. +// { dg-do compile { target c++2a } } +// { dg-options "-Wno-volatile" } + +#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x)) + +struct S { + volatile int a : 4; + int b : 2; +}; + +struct T { + int a : 4; + int b : 2; +}; + +union U { + char c; + int i; +}; + +struct W { + W(); + W(volatile W&); + W& operator=(volatile W&) volatile; +}; + +volatile int +fn (volatile int i) +{ + volatile int v = 10; + int *volatile p = nullptr; + + // Pre/post ++/--. + v++; + ++v; + v--; + --v; + p++; + ++p; + p--; + --p; + return v + i + *p; +} + +void +fn2 () +{ + volatile int vi = 42; + int i = 24; + + // Discarded-value expression ([expr.context]). + // The lvalue-to-rvalue conversion is applied here: + vi; + // ...but not here. Otherwise we'd write to VI and then immediately read it. + vi = 42; + vi = i; + vi = i = 42; + i = vi = 42; + &(vi = i); + (vi = 42, 45); + (i = vi = 42, 10); + i = vi; // LHS not volatile. + i = (vi = i, 42); + static_cast(vi = i); + static_cast(i = vi = 42); + (void)(vi = i); + (void)(i = vi = 42); + + // Unevaluated operand. + decltype(vi = 42) x = vi; + decltype(i = vi = 42) x3 = i; + + // Compound assignments. + vi += i; + vi -= i; + vi %= i; + vi ^= i; + vi |= i; + vi /= i; + vi = vi += 42; + vi += vi = 42; + i *= vi; + decltype(vi -= 42) x2 = vi; + + // Structured bindings. + int a[] = { 10, 5 }; + const auto & [cxr, cyr] = a; + const volatile auto & [cvxr, cvyr] = a; + volatile auto & [vxr, vyr] = a; +} + +void +fn3 () +{ + volatile int i, j, k = 0; + i = j = k; + + ACCESS_ONCE(j); + + S s; + s.b = 1; + + volatile U u; + u.c = 42; + i = u.c = 42; + u.c += 42; + + volatile T t; + t.a = 3; + j = t.a = 3; + t.a += 3; + + volatile int *src = &i; + *src; // No assignment, don't warn. +} + +void +fn4 () +{ + volatile W vw; + W w; + // Assignment to objects of a class is defined by the copy/move assignment + // operator. + vw = w; + w = vw; +} + +template +void raccoon () +{ + volatile T t, u; + t = 42; + u = t = 42; + t &= 42; +} + +void +fn5 () +{ + raccoon(); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile3.C b/gcc/testsuite/g++.dg/cpp2a/volatile3.C new file mode 100644 index 00000000000..f10a29756a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/volatile3.C @@ -0,0 +1,142 @@ +// PR c++/91361 - P1152R4: Deprecating some uses of volatile. +// { dg-do compile { target c++17 } } +// { dg-options "-Wvolatile" } + +#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x)) + +struct S { + volatile int a : 4; + int b : 2; +}; + +struct T { + int a : 4; + int b : 2; +}; + +union U { + char c; + int i; +}; + +struct W { + W(); + W(volatile W&); + W& operator=(volatile W&) volatile; +}; + +volatile int // { dg-warning ".volatile.-qualified return type is deprecated" } +fn (volatile int i) // { dg-warning ".volatile.-qualified parameter is deprecated" } +{ + volatile int v = 10; + int *volatile p = nullptr; + + // Pre/post ++/--. + v++; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + ++v; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + v--; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + --v; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + p++; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + ++p; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + p--; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + --p; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + return v + i + *p; +} + +void +fn2 () +{ + volatile int vi = 42; + int i = 24; + + // Discarded-value expression ([expr.context]). + // The lvalue-to-rvalue conversion is applied here: + vi; + // ...but not here. Otherwise we'd write to VI and then immediately read it. + vi = 42; + vi = i; + vi = i = 42; + i = vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + &(vi = i); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + (vi = 42, 45); + (i = vi = 42, 10); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + i = vi; // LHS not volatile. + i = (vi = i, 42); + static_cast(vi = i); + static_cast(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + (void)(vi = i); + (void)(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + // Unevaluated operand. + decltype(vi = 42) x = vi; + decltype(i = vi = 42) x3 = i; + + // Compound assignments. + vi += i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi -= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi %= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi ^= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi |= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi /= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi = vi += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi += vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + i *= vi; + decltype(vi -= 42) x2 = vi; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + // Structured bindings. + int a[] = { 10, 5 }; + const auto & [cxr, cyr] = a; + const volatile auto & [cvxr, cvyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" } + volatile auto & [vxr, vyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" } +} + +void +fn3 () +{ + volatile int i, j, k = 0; + i = j = k; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + ACCESS_ONCE(j); + + S s; + s.b = 1; + + volatile U u; + u.c = 42; + i = u.c = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + u.c += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + volatile T t; + t.a = 3; + j = t.a = 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + t.a += 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + volatile int *src = &i; + *src; // No assignment, don't warn. +} + +void +fn4 () +{ + volatile W vw; + W w; + // Assignment to objects of a class is defined by the copy/move assignment + // operator. + vw = w; + w = vw; +} + +template +void raccoon () +{ + volatile T t, u; + t = 42; + u = t = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + t &= 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } +} + +void +fn5 () +{ + raccoon(); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile4.C b/gcc/testsuite/g++.dg/cpp2a/volatile4.C new file mode 100644 index 00000000000..2148cdeb3d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/volatile4.C @@ -0,0 +1,142 @@ +// PR c++/91361 - P1152R4: Deprecating some uses of volatile. +// { dg-do compile { target c++2a } } +// { dg-options "-Wno-deprecated" } + +#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x)) + +struct S { + volatile int a : 4; + int b : 2; +}; + +struct T { + int a : 4; + int b : 2; +}; + +union U { + char c; + int i; +}; + +struct W { + W(); + W(volatile W&); + W& operator=(volatile W&) volatile; +}; + +volatile int +fn (volatile int i) +{ + volatile int v = 10; + int *volatile p = nullptr; + + // Pre/post ++/--. + v++; + ++v; + v--; + --v; + p++; + ++p; + p--; + --p; + return v + i + *p; +} + +void +fn2 () +{ + volatile int vi = 42; + int i = 24; + + // Discarded-value expression ([expr.context]). + // The lvalue-to-rvalue conversion is applied here: + vi; + // ...but not here. Otherwise we'd write to VI and then immediately read it. + vi = 42; + vi = i; + vi = i = 42; + i = vi = 42; + &(vi = i); + (vi = 42, 45); + (i = vi = 42, 10); + i = vi; // LHS not volatile. + i = (vi = i, 42); + static_cast(vi = i); + static_cast(i = vi = 42); + (void)(vi = i); + (void)(i = vi = 42); + + // Unevaluated operand. + decltype(vi = 42) x = vi; + decltype(i = vi = 42) x3 = i; + + // Compound assignments. + vi += i; + vi -= i; + vi %= i; + vi ^= i; + vi |= i; + vi /= i; + vi = vi += 42; + vi += vi = 42; + i *= vi; + decltype(vi -= 42) x2 = vi; + + // Structured bindings. + int a[] = { 10, 5 }; + const auto & [cxr, cyr] = a; + const volatile auto & [cvxr, cvyr] = a; + volatile auto & [vxr, vyr] = a; +} + +void +fn3 () +{ + volatile int i, j, k = 0; + i = j = k; + + ACCESS_ONCE(j); + + S s; + s.b = 1; + + volatile U u; + u.c = 42; + i = u.c = 42; + u.c += 42; + + volatile T t; + t.a = 3; + j = t.a = 3; + t.a += 3; + + volatile int *src = &i; + *src; // No assignment, don't warn. +} + +void +fn4 () +{ + volatile W vw; + W w; + // Assignment to objects of a class is defined by the copy/move assignment + // operator. + vw = w; + w = vw; +} + +template +void raccoon () +{ + volatile T t, u; + t = 42; + u = t = 42; + t &= 42; +} + +void +fn5 () +{ + raccoon(); +} diff --git a/gcc/testsuite/g++.dg/expr/bool3.C b/gcc/testsuite/g++.dg/expr/bool3.C index 373c202b800..f27399cfc8a 100644 --- a/gcc/testsuite/g++.dg/expr/bool3.C +++ b/gcc/testsuite/g++.dg/expr/bool3.C @@ -13,8 +13,10 @@ int main() b++; // { dg-warning "deprecated" "" { target { ! c++17 } } } // { dg-error "forbidden" "" { target c++17 } .-1 } + // { dg-warning ".volatile.-qualified type is deprecated" "" { target c++2a } .-2 } b++; // { dg-warning "deprecated" "" { target { ! c++17 } } } // { dg-error "forbidden" "" { target c++17 } .-1 } + // { dg-warning ".volatile.-qualified type is deprecated" "" { target c++2a } .-2 } i = b; if (i != 1) abort (); diff --git a/gcc/testsuite/g++.dg/expr/bool4.C b/gcc/testsuite/g++.dg/expr/bool4.C index dce51ec332e..5891bc311bd 100644 --- a/gcc/testsuite/g++.dg/expr/bool4.C +++ b/gcc/testsuite/g++.dg/expr/bool4.C @@ -8,6 +8,6 @@ int main() { my_bool b = false; b--; // { dg-error "" } + // { dg-warning ".volatile.-qualified type is deprecated" "" { target c++2a } .-1 } return 0; } - diff --git a/gcc/testsuite/g++.dg/expr/cond9.C b/gcc/testsuite/g++.dg/expr/cond9.C index b344c1f683a..f7e092e1445 100644 --- a/gcc/testsuite/g++.dg/expr/cond9.C +++ b/gcc/testsuite/g++.dg/expr/cond9.C @@ -4,7 +4,7 @@ struct A { // { dg-message "A" } A(int); }; -void foo(volatile A a) { +void foo(volatile A a) { // { dg-warning "deprecated" "" { target c++2a } } 1 ? a : 0; // { dg-error "qualifiers|lvalue|no match" } 1 ? 0 : a; // { dg-error "qualifiers|lvalue|no match" } } diff --git a/gcc/testsuite/g++.dg/ext/vector25.C b/gcc/testsuite/g++.dg/ext/vector25.C index 6c1f5d09878..339865d6942 100644 --- a/gcc/testsuite/g++.dg/ext/vector25.C +++ b/gcc/testsuite/g++.dg/ext/vector25.C @@ -2,5 +2,5 @@ volatile int i __attribute__((vector_size(8))); void foo() { - i += i; + i += i; // { dg-warning "deprecated" "" { target c++2a } } } diff --git a/gcc/testsuite/g++.dg/gomp/depend-iterator-1.C b/gcc/testsuite/g++.dg/gomp/depend-iterator-1.C index 6f4aa97ee44..d12670c5159 100644 --- a/gcc/testsuite/g++.dg/gomp/depend-iterator-1.C +++ b/gcc/testsuite/g++.dg/gomp/depend-iterator-1.C @@ -1,3 +1,5 @@ +// { dg-additional-options "-Wno-volatile" } + int arr[64], arr2[64]; struct S { int a[4]; } k; short arr4[4]; diff --git a/gcc/testsuite/g++.dg/inherit/covariant21.C b/gcc/testsuite/g++.dg/inherit/covariant21.C index 42cdf870081..769cb14ecbc 100644 --- a/gcc/testsuite/g++.dg/inherit/covariant21.C +++ b/gcc/testsuite/g++.dg/inherit/covariant21.C @@ -6,12 +6,12 @@ struct C : A, B {}; struct X { - virtual B* foo(volatile int); + virtual B* foo(volatile int); // { dg-warning "deprecated" "" { target c++2a } } }; struct Y : X { - virtual C* foo(volatile int); + virtual C* foo(volatile int); // { dg-warning "deprecated" "" { target c++2a } } }; -C* Y::foo(volatile int) { return 0; } +C* Y::foo(volatile int) { return 0; } // { dg-warning "deprecated" "" { target c++2a } } diff --git a/gcc/testsuite/g++.dg/init/ref18.C b/gcc/testsuite/g++.dg/init/ref18.C index e704077c26b..81ac76a40d3 100644 --- a/gcc/testsuite/g++.dg/init/ref18.C +++ b/gcc/testsuite/g++.dg/init/ref18.C @@ -1,6 +1,6 @@ // PR c++/49395 -volatile int foo(); +volatile int foo(); // { dg-warning "deprecated" "" { target c++2a } } struct A { volatile int i; }; typedef volatile int vi; diff --git a/gcc/testsuite/g++.dg/ipa/pr63838.C b/gcc/testsuite/g++.dg/ipa/pr63838.C index d23b3133748..5b6b11d70e5 100644 --- a/gcc/testsuite/g++.dg/ipa/pr63838.C +++ b/gcc/testsuite/g++.dg/ipa/pr63838.C @@ -7,12 +7,12 @@ __attribute__((noinline, noclone)) static void bar (int); volatile int v; void (*fn) (); -struct S { S () { v++; } ~S () { v++; } }; +struct S { S () { v++; } ~S () { v++; } }; // { dg-warning "deprecated" "" { target c++2a } } __attribute__((noinline, noclone)) static void foo (int x) { - v++; + v++; // { dg-warning "deprecated" "" { target c++2a } } if (x == 5) bar (x); } @@ -20,7 +20,7 @@ foo (int x) __attribute__((noinline, noclone)) static void bar (int x) { - v++; + v++; // { dg-warning "deprecated" "" { target c++2a } } if (x == 6) foo (x); else if (x == 5) diff --git a/gcc/testsuite/g++.dg/overload/rvalue2.C b/gcc/testsuite/g++.dg/overload/rvalue2.C index 8a2290dc293..a829fb5e8cc 100644 --- a/gcc/testsuite/g++.dg/overload/rvalue2.C +++ b/gcc/testsuite/g++.dg/overload/rvalue2.C @@ -7,5 +7,5 @@ template void f(const T&); int main() { volatile int i = 0; - f(i++); + f(i++); // { dg-warning "deprecated" "" { target c++2a } } } diff --git a/gcc/testsuite/g++.dg/parse/semicolon4.C b/gcc/testsuite/g++.dg/parse/semicolon4.C index 5135ec14b1f..bdd1c845187 100644 --- a/gcc/testsuite/g++.dg/parse/semicolon4.C +++ b/gcc/testsuite/g++.dg/parse/semicolon4.C @@ -25,7 +25,7 @@ struct E1 } const; // { dg-error "'const' can only be specified for objects and functions" } void foo ( -struct E2 +struct E2 // { dg-warning "deprecated" "" { target c++2a } } { // { dg-error "types may not be defined in parameter types" } int i; } volatile); diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C b/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C index 4f02678e7f9..24a6b41cbd8 100644 --- a/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C +++ b/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C @@ -3,6 +3,7 @@ /* { dg-options "-Wignored-qualifiers" } */ volatile void bar(); /* { dg-warning "type qualifiers ignored" } */ +// { dg-warning ".volatile.-qualified return type is deprecated" "" { target c++2a } .-1 } struct A { diff --git a/gcc/testsuite/g++.dg/warn/pr36069.C b/gcc/testsuite/g++.dg/warn/pr36069.C index efb35c25716..7b166351a4b 100644 --- a/gcc/testsuite/g++.dg/warn/pr36069.C +++ b/gcc/testsuite/g++.dg/warn/pr36069.C @@ -6,11 +6,13 @@ struct foo { bool a; volatile bool b,c; foo() { a = b = c = false; } // { dg-bogus "parentheses" } + // { dg-warning "deprecated" "" { target c++2a } .-1 } }; int main() { bool a; volatile bool b,c; a = b = c = false; // { dg-bogus "parentheses" } + // { dg-warning "deprecated" "" { target c++2a } .-1 } foo A; } diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p9506.C b/gcc/testsuite/g++.old-deja/g++.mike/p9506.C index db16e3738e2..97594640f96 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p9506.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p9506.C @@ -3,5 +3,5 @@ char * volatile p; void foo() { - --p = 0; + --p = 0; // { dg-warning "deprecated" "" { target c++2a } } } diff --git a/gcc/testsuite/g++.old-deja/g++.other/volatile1.C b/gcc/testsuite/g++.old-deja/g++.other/volatile1.C index 7d818fbe9e1..a93ef58aa9f 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/volatile1.C +++ b/gcc/testsuite/g++.old-deja/g++.other/volatile1.C @@ -5,7 +5,7 @@ class f_class // { dg-message "note" "candidates" } { }; -volatile f_class +volatile f_class // { dg-warning "deprecated" "" { target c++2a } } ret_v_f_class() { f_class t;