From patchwork Sat Jul 20 17:29:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JeanHeyd Meneide X-Patchwork-Id: 1134417 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-505375-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="rUuVI12D"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="fsds9GW/"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45rZdg6Lmbz9s7T for ; Sun, 21 Jul 2019 03:30:29 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=Ch7sPt66od6KvlZS2NUXFD6BCIIjDc1m1/1ej5w52Juet2 L8JZbbEzujVZg2kG86VEtDJmCqOBR2OPpZTI8A7zmZp+R69VAGrxctrawHfHj4oH IJytdHERTp1TfzAeNsKB9p4TbxQwmeL+kIbtTWbBRkDYbvGqo4Fj0GsWfQ5Dc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=5C+JJk7h1gXsPGa5ReW8vPmPLHk=; b=rUuVI12DeieMr10mQiHm Y9iZ4kL2DsRirPyEJ3VwxmweUUq+AEHdatyqL4+NMb676sJf44BVvJPP4Vm87K8Z LqpxNpzhQMfEoHNkJ3l0TekcC9v5HNIdnPyYghyX3j1b6/IX8q+e0aOzzd0O7nFm PGzYpJcK5lktJ4JBWZ5KBCk= Received: (qmail 15523 invoked by alias); 20 Jul 2019 17:30:20 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 15514 invoked by uid 89); 20 Jul 2019 17:30:19 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, HTML_MESSAGE, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPAM_BODY, SPF_PASS autolearn=ham version=3.3.1 spammy=bj, Draft, Committee, bi X-HELO: mail-vs1-f43.google.com Received: from mail-vs1-f43.google.com (HELO mail-vs1-f43.google.com) (209.85.217.43) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 20 Jul 2019 17:30:14 +0000 Received: by mail-vs1-f43.google.com with SMTP id a186so21920749vsd.7 for ; Sat, 20 Jul 2019 10:30:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=Cb6dtKgth06PfT324+Lg/ahUGEAiNNS4xT0G5oaxKLw=; b=fsds9GW/xs/7jckvNsWFRgQXKKBxNvrz9jTfMGXyfjXtrsMcJLoqM5SAxJolAobhvh 0mfnkPSSyu1Fld1uQZpwSeqCfvjopqFKbwGk4/jo7tSJElokjRGUS0qoS+iYe8aJwpBZ eDaf4ZWluyKZmJS0QJwMx1P5eohdc7P9g1WI08odWBQoPq97uRf8H880G25Gspzb4BrG bPG56sbTrfC+OsxP1HGygxBdGDOkAZd0QFpdv3I+7+gWW+D+FwWOVqS+eWXIjStV4muC NidszLXriqAqJXyaB2PAKV0uJWToy4xSk0yM/1FSsiDQvG5bDAcOcbRLCBdrPznuvoio WvZA== MIME-Version: 1.0 From: JeanHeyd Meneide Date: Sat, 20 Jul 2019 19:29:55 +0200 Message-ID: Subject: cp: implementation of p1301 for C++ To: gcc-patches@gcc.gnu.org X-IsSubscribed: yes Dear GCC Community, This patch implements the recently accepted p1301: [[nodiscard("should have a reason")]]. Aaron Ballman implemented it for Clang in http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20190715/280158.html -- this is in preparation for a paper that will soon go to the C Committee to keep feature-parity with C++ (the C2x draft already has attributes with syntax exactly like C++). Comments welcome: this is my first patch, and probably needs a lot of help. This is also part of my Google Summer of Code training, to get used to submitting and sending patches on the gcc-patches list. Sincerely, ThePhD ---------------- diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index e6452542bcc..3db90ec6c66 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2019-07-20 ThePhD + + * c-family/c-lex.c: increase [[nodiscard]] feature macro value (final value pending post-Cologne mailing) + 2019-07-20 Jakub Jelinek * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_LOOP. diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c index 851fd704e5d..f2c0b62c95b 100644 --- a/gcc/c-family/c-lex.c +++ b/gcc/c-family/c-lex.c @@ -353,13 +353,14 @@ c_common_has_attribute (cpp_reader *pfile) else if (is_attribute_p ("deprecated", attr_name)) result = 201309; else if (is_attribute_p ("maybe_unused", attr_name) - || is_attribute_p ("nodiscard", attr_name) || is_attribute_p ("fallthrough", attr_name)) result = 201603; else if (is_attribute_p ("no_unique_address", attr_name) || is_attribute_p ("likely", attr_name) || is_attribute_p ("unlikely", attr_name)) result = 201803; + else if (is_attribute_p ("nodiscard", attr_name)) + result = 201907; /* placeholder until C++20 Post-Cologne Working Draft. */ if (result) attr_name = NULL_TREE; } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d645cdef147..9877b1af517 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2019-07-20 ThePhD + + * escaped_string.h: New. Refactored out of tree.c to make more + broadly available (e.g. to parser.c, cvt.c). + * tree.c: Implement p1301 - nodiscard("should have a reason")) + Moved escaped_string class for working with attributes to + dedicated header. + Added C++2a nodiscard string message handling. + Increase nodiscard argument handling max_length from 0 + to 1. (error C++2a gated) + * parser.c: add requirement that nodiscard only be seen + once in attribute-list (C++2a gated) + * cvt.c: add nodiscard message to output, if applicable + 2019-07-20 Jason Merrill * cp-tree.h (ovl_iterator::using_p): A USING_DECL by itself was also diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 23d2aabc483..aa4816f3a4f 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "convert.h" #include "stringpool.h" #include "attribs.h" +#include "escaped_string.h" static tree convert_to_pointer_force (tree, tree, tsubst_flags_t); static tree build_type_conversion (tree, tree); @@ -1029,19 +1030,29 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit) if (implicit != ICV_CAST && fn && lookup_attribute ("nodiscard", DECL_ATTRIBUTES (fn))) { - auto_diagnostic_group d; + tree attr = DECL_ATTRIBUTES (fn); + escaped_string msg; + if (attr) + msg.escape (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + bool has_msg = static_cast(msg); + auto_diagnostic_group d; if (warning_at (loc, OPT_Wunused_result, - "ignoring return value of %qD, " - "declared with attribute nodiscard", fn)) - inform (DECL_SOURCE_LOCATION (fn), "declared here"); + "ignoring return value of %qD, " + "declared with attribute nodiscard%s%s", fn, (has_msg ? ": " : ""), (has_msg ? (const char*)msg : ""))) + inform (DECL_SOURCE_LOCATION (fn), "declared here"); } else if (implicit != ICV_CAST && lookup_attribute ("nodiscard", TYPE_ATTRIBUTES (rettype))) { + tree attr = TYPE_ATTRIBUTES (rettype); + escaped_string msg; + if (attr) + msg.escape (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + bool has_msg = static_cast(msg); auto_diagnostic_group d; if (warning_at (loc, OPT_Wunused_result, - "ignoring returned value of type %qT, " - "declared with attribute nodiscard", rettype)) + "ignoring returned value of type %qT, " + "declared with attribute nodiscard%s%s", rettype, (has_msg ? ": " : ""), (has_msg ? (const char*)msg : ""))) { if (fn) inform (DECL_SOURCE_LOCATION (fn), diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 5c379aaf58d..d66d13615fc 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -26399,13 +26399,26 @@ cp_parser_check_std_attribute (tree attributes, tree attribute) { tree name = get_attribute_name (attribute); if (is_attribute_p ("noreturn", name) - && lookup_attribute ("noreturn", attributes)) - error ("attribute % can appear at most once " - "in an attribute-list"); + && lookup_attribute ("noreturn", attributes)) + { + error ("attribute % can appear at most once " + "in an attribute-list"); + } else if (is_attribute_p ("deprecated", name) && lookup_attribute ("deprecated", attributes)) - error ("attribute % can appear at most once " - "in an attribute-list"); + { + error ("attribute % can appear at most once " + "in an attribute-list"); + } + else if (cxx_dialect >= cxx2a) + { + if (is_attribute_p ("nodiscard", name) + && lookup_attribute ("nodiscard", attributes)) + { + error ("attribute % can appear at most once " + "in an attribute-list"); + } + } } } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 37e24a1669c..8c2d056f3eb 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -4356,9 +4356,27 @@ zero_init_p (const_tree t) warn_unused_result attribute. */ static tree -handle_nodiscard_attribute (tree *node, tree name, tree /*args*/, +handle_nodiscard_attribute (tree *node, tree name, tree args, int /*flags*/, bool *no_add_attrs) { + if (!args) + *no_add_attrs = true; + else if (cxx_dialect >= cxx2a) + { + if (TREE_CODE (TREE_VALUE (args)) != STRING_CST) + { + error ("nodiscard attribute argument must be a string"); + *no_add_attrs = true; + } + } + else + { + if (!*no_add_attrs) + { + error("nodiscard attribute does not take any arguments: use flag %<-std=c2a%> or better to compile your code"); + } + } + if (TREE_CODE (*node) == FUNCTION_DECL) { if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (*node)))) @@ -4447,7 +4465,7 @@ const struct attribute_spec std_attribute_table[] = affects_type_identity, handler, exclude } */ { "maybe_unused", 0, 0, false, false, false, false, handle_unused_attribute, NULL }, - { "nodiscard", 0, 0, false, false, false, false, + { "nodiscard", 0, 1, false, false, false, false, handle_nodiscard_attribute, NULL }, { "no_unique_address", 0, 0, true, false, false, false, handle_no_unique_addr_attribute, NULL }, diff --git a/gcc/escaped_string.h b/gcc/escaped_string.h new file mode 100644 index 00000000000..8c9a236da41 --- /dev/null +++ b/gcc/escaped_string.h @@ -0,0 +1,41 @@ +/* Shared escaped string class. + Copyright (C) 1999-2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_ESCAPED_STRING_H +#define GCC_ESCAPED_STRING_H + +#include + +/* A class to handle converting a string that might contain + control characters, (eg newline, form-feed, etc), into one + in which contains escape sequences instead. */ + +class escaped_string +{ + public: + escaped_string () { m_owned = false; m_str = NULL; }; + ~escaped_string () { if (m_owned) free (m_str); } + operator const char *() const { return (const char *) m_str; } + void escape (const char *); + private: + char *m_str; + bool m_owned; +}; + +#endif /* ! GCC_ESCAPED_STRING_H */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index adefdb937ab..e521a38eac6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-07-20 ThePhD + + * g++.dg/cpp2a/nodiscard-reason.C: New test. + * g++.dg/cpp2a/nodiscard-once.C: New test. + * g++.dg/cpp2a/nodiscard-once-clause.C: New test. + * g++.dg/cpp2a/nodiscard-bad-clause.C: New test. + 2019-07-20 Jakub Jelinek * c-c++-common/gomp/cancel-1.c: Adjust expected diagnostic wording. @@ -16,6 +23,13 @@ * gcc.dg/vect/vect-simd-16.c: New test. +2019-07-20 ThePhD + + * g++.dg/cpp2a/nodiscard-reason.C: New test; check nodiscard reason string is applied. + * g++.dg/cpp2a/nodiscard-once.C: New test; check nodiscard can only be used once. + * g++.dg/cpp2a/nodiscard-once-clause.C: New test; check nodiscard arguments can only have one. + * g++.dg/cpp2a/nodiscard-bad-clause.C: New test; check nodiscard does not accept non-string-literals. + 2019-07-19 Jeff Law * gcc.dg/tree-ssa/ssa-dse-37.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp2a/nodiscard-bad-clause.C b/gcc/testsuite/g++.dg/cpp2a/nodiscard-bad-clause.C new file mode 100644 index 00000000000..2d242ee7abd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nodiscard-bad-clause.C @@ -0,0 +1,12 @@ +/* nodiscard attribute tests */ +/* { dg-do compile { target c++2a } } */ +/* { dg-options "-O -ftrack-macro-expansion=0" } */ + +[[nodiscard(123)]] int check1 (void); /* { dg-error "nodiscard attribute argument.*must be a string" } */ + +void +test (void) +{ + check1 (); /* { dg-warning "nodiscard" } */ + (void) check1 (); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/nodiscard-once-clause.C b/gcc/testsuite/g++.dg/cpp2a/nodiscard-once-clause.C new file mode 100644 index 00000000000..11b1c6a9128 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nodiscard-once-clause.C @@ -0,0 +1,12 @@ +/* nodiscard attribute tests */ +/* { dg-do compile { target c++2a } } */ +/* { dg-options "-O -ftrack-macro-expansion=0" } */ + +[[nodiscard("not", "allowed")]] int check1 (void); /* { dg-error "wrong number of arguments..*nodiscard" } */ + +void +test (void) +{ + check1 (); /* { dg-warning "nodiscard" } */ + (void) check1 (); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/nodiscard-once.C b/gcc/testsuite/g++.dg/cpp2a/nodiscard-once.C new file mode 100644 index 00000000000..cf34812ed3f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nodiscard-once.C @@ -0,0 +1,12 @@ +/* nodiscard attribute tests */ +/* { dg-do compile { target c++2a } } */ +/* { dg-options "-O -ftrack-macro-expansion=0" } */ + +[[nodiscard, nodiscard]] int check1 (void); /* { dg-error ".nodiscard..*can appear at most once" } */ + +void +test (void) +{ + check1 (); /* { dg-warning "nodiscard" } */ + (void) check1 (); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason.C b/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason.C new file mode 100644 index 00000000000..ea29be32ecb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nodiscard-reason.C @@ -0,0 +1,203 @@ +/* nodiscard attribute tests, adapted from gcc.dg/attr-warn-unused-result.c. */ +/* { dg-do compile { target c++2a } } */ +/* { dg-options "-O -ftrack-macro-expansion=0" } */ + +#define NODIS [[nodiscard("exact_message")]] +#define NODISAI [[nodiscard("exact_inline_message"), gnu::always_inline]] inline +enum [[nodiscard("exact_E_message")]] E { e }; +typedef E (*fnt) (void); + +typedef struct { long i; } A; +typedef struct { long i; long j; } B; +typedef struct { char big[1024]; fnt fn; } C; +struct [[nodiscard("exact_D_message")]] D { int i; D(); ~D(); }; + +NODIS E check1 (void); +NODIS void check2 (void); /* { dg-warning "10:.nodiscard..*exact_message" } */ +NODIS int foo; /* { dg-warning "9:.nodiscard..*exact_message" } */ +int bar (void); +NODISAI E check3 (void) { return (E)bar (); } +NODIS A check4 (void); +NODIS B check5 (void); +NODIS C check6 (void); +A bar7 (void); +B bar8 (void); +C bar9 (void); +NODISAI A check7 (void) { return bar7 (); } +NODISAI B check8 (void) { return bar8 (); } +NODISAI C check9 (void) { return bar9 (); } +/* This is useful for checking whether return value of statement + expressions (returning int in this case) is used. */ +NODISAI int check_int_result (int res) { return res; } +#define GU(v) ({ int e = 0; (v) = bar (); if ((v) < 23) e = 14; e; }) +fnt fnptr; +NODIS E check10 (void); +int baz (void); +NODISAI E check11 (void) { return (E)baz (); } +int k; + +D check12(); + +void +test (void) +{ + int i = 0, j; + const fnt pcheck1 = check1; + const fnt pcheck3 = check3; + A a; + B b; + C c; + D d; + if (check1 ()) + return; + i += check1 (); + i += ({ check1 (); }); + check1 (); /* { dg-warning "nodiscard.*exact_message" } */ + (void) check1 (); + check1 (), bar (); /* { dg-warning "nodiscard.*exact_message" } */ + check2 (); + (void) check2 (); + check2 (), bar (); + if (check3 ()) + return; + i += check3 (); + i += ({ check3 (); }); + check3 (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + (void) check3 (); + check3 (), bar (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + a = check4 (); + if (a.i) + return; + if (check4 ().i) + return; + if (({ check4 (); }).i) + return; + check4 (); /* { dg-warning "nodiscard.*exact_message" } */ + (void) check4 (); + check4 (), bar (); /* { dg-warning "nodiscard.*exact_message" } */ + b = check5 (); + if (b.i + b.j) + return; + if (check5 ().j) + return; + if (({ check5 (); }).j) + return; + check5 (); /* { dg-warning "nodiscard.*exact_message" } */ + (void) check5 (); + check5 (), bar (); /* { dg-warning "nodiscard.*exact_message" } */ + c = check6 (); + if (c.big[12] + c.big[29]) + return; + if (check6 ().big[27]) + return; + if (({ check6 (); }).big[0]) + return; + check6 (); /* { dg-warning "nodiscard.*exact_message" } */ + (void) check6 (); + check6 (), bar (); /* { dg-warning "nodiscard.*exact_message" } */ + a = check7 (); + if (a.i) + return; + if (check7 ().i) + return; + if (({ check7 (); }).i) + return; + check7 (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + (void) check7 (); + check7 (), bar (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + b = check8 (); + if (b.i + b.j) + return; + if (check8 ().j) + return; + if (({ check8 (); }).j) + return; + check8 (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + (void) check8 (); + check8 (), bar (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + c = check9 (); + if (c.big[12] + c.big[29]) + return; + if (check9 ().big[27]) + return; + if (({ check9 (); }).big[0]) + return; + check9 (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + (void) check9 (); + check9 (), bar (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + if (check_int_result (GU (j))) + return; + i += check_int_result (GU (j)); + i += ({ check_int_result (GU (j)); }); + check_int_result (GU (j)); /* { dg-warning "nodiscard.*exact_inline_message" } */ + (void) check_int_result (GU (j)); + check_int_result (GU (j)), bar (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + if (fnptr ()) + return; + i += fnptr (); + i += ({ fnptr (); }); + fnptr (); /* { dg-warning "nodiscard.*exact_E_message" } */ + (void) fnptr (); + fnptr (), bar (); /* { dg-warning "nodiscard.*exact_E_message" } */ + fnptr = check1; + if (fnptr ()) + return; + i += fnptr (); + i += ({ fnptr (); }); + fnptr (); /* { dg-warning "nodiscard.*exact_E_message" } */ + (void) fnptr (); + fnptr (), bar (); /* { dg-warning "nodiscard.*exact_E_message" } */ + fnptr = check3; + if (fnptr ()) + return; + i += fnptr (); + i += ({ fnptr (); }); + fnptr (); /* { dg-warning "nodiscard.*exact_E_message" } */ + (void) fnptr (); + fnptr (), bar (); /* { dg-warning "nodiscard.*exact_E_message" } */ + if (bar9 ().fn ()) + return; + i += bar9 ().fn (); + i += ({ bar9 ().fn (); }); + bar9 ().fn (); /* { dg-warning "nodiscard.*exact_E_message" } */ + (void) bar9 ().fn (); + bar9 ().fn (), bar (); /* { dg-warning "nodiscard.*exact_E_message" } */ + if ((k ? check1 : check10) ()) + return; + i += (k ? check1 : check10) (); + i += ({ (k ? check1 : check10) (); }); + (k ? check1 : check10) (); /* { dg-warning "nodiscard.*exact_E_message" } */ + (void) (k ? check1 : check10) (); + (k ? check1 : check10) (), bar (); /* { dg-warning "nodiscard.*exact_E_message" } */ + if ((k ? check3 : check11) ()) + return; + i += (k ? check3 : check11) (); + i += ({ (k ? check3 : check11) (); }); + (k ? check3 : check11) (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + (void) (k ? check3 : check11) (); + (k ? check3 : check11) (), bar (); /* { dg-warning "nodiscard.*exact_inline_message" } */ + if (pcheck1 ()) + return; + i += pcheck1 (); + i += ({ pcheck1 (); }); + pcheck1 (); /* { dg-warning "nodiscard.*exact_E_message" } */ + (void) pcheck1 (); + pcheck1 (), bar (); /* { dg-warning "nodiscard.*exact_E_message" } */ + if (pcheck3 ()) + return; + i += pcheck3 (); + i += ({ pcheck3 (); }); + pcheck3 (); /* { dg-warning "nodiscard.*exact_E_message" } */ + (void) pcheck3 (); + pcheck3 (), bar (); /* { dg-warning "nodiscard.*exact_E_message" } */ + d = check12 (); + if (d.i) + return; + if (check12 ().i) + return; + if (({ check12 (); }).i) + return; + check12 (); /* { dg-warning "nodiscard.*exact_D_message" } */ + (void) check12 (); + check12 (), bar (); /* { dg-warning "nodiscard.*exact_D_message" } */ +} diff --git a/gcc/tree.c b/gcc/tree.c index 8cf75f22220..362e07d1c33 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "backend.h" #include "target.h" #include "tree.h" +#include "escaped_string.h" #include "gimple.h" #include "tree-pass.h" #include "ssa.h" @@ -13132,22 +13133,6 @@ typedef_variant_p (const_tree type) return is_typedef_decl (TYPE_NAME (type)); } -/* A class to handle converting a string that might contain - control characters, (eg newline, form-feed, etc), into one - in which contains escape sequences instead. */ - -class escaped_string -{ - public: - escaped_string () { m_owned = false; m_str = NULL; }; - ~escaped_string () { if (m_owned) free (m_str); } - operator const char *() const { return (const char *) m_str; } - void escape (const char *); - private: - char *m_str; - bool m_owned; -}; - /* PR 84195: Replace control characters in "unescaped" with their escaped equivalents. Allow newlines if -fmessage-length has been set to a non-zero value. This is done here, rather than