mirror of git://gcc.gnu.org/git/gcc.git
Implement C++20 P1301 [[nodiscard("should have a reason")]].
2019-10-17 JeanHeyd Meneide <phdofthehouse@gmail.com> gcc/ * escaped_string.h (escaped_string): New header. * tree.c (escaped_string): Remove escaped_string class. gcc/c-family * c-lex.c (c_common_has_attribute): Update nodiscard value. gcc/cp/ * tree.c (handle_nodiscard_attribute) Added C++2a nodiscard string message. (std_attribute_table) Increase nodiscard argument handling max_length from 0 to 1. * parser.c (cp_parser_check_std_attribute): Add requirement that nodiscard only be seen once in attribute-list. (cp_parser_std_attribute): Check that empty parenthesis lists are not specified for attributes that have max_length > 0 (e.g. [[attr()]]). * cvt.c (maybe_warn_nodiscard): Add nodiscard message to output, if applicable. (convert_to_void): Allow constructors to be nodiscard-able (P1771). gcc/testsuite/g++.dg/cpp0x * gen-attrs-67.C: Test new error message for empty-parenthesis-list. gcc/testsuite/g++.dg/cpp2a * nodiscard-construct.C: New test. * nodiscard-once.C: New test. * nodiscard-reason-nonstring.C: New test. * nodiscard-reason-only-one.C: New test. * nodiscard-reason.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com> From-SVN: r277200
This commit is contained in:
parent
9299523c9a
commit
8ad0c477e8
|
@ -1,3 +1,8 @@
|
|||
2019-10-17 JeanHeyd Meneide <phdofthehouse@gmail.com>
|
||||
|
||||
* escaped_string.h (escaped_string): New header.
|
||||
* tree.c (escaped_string): Remove escaped_string class.
|
||||
|
||||
2019-10-18 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR tree-optimization/92157
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2019-10-17 JeanHeyd Meneide <phdofthehouse@gmail.com>
|
||||
|
||||
* c-lex.c (c_common_has_attribute): Update nodiscard value.
|
||||
|
||||
2019-10-14 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* c-common.h (user_facing_original_type_p): Declare.
|
||||
|
|
|
@ -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;
|
||||
if (result)
|
||||
attr_name = NULL_TREE;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
2019-10-17 JeanHeyd Meneide <phdofthehouse@gmail.com>
|
||||
|
||||
Implement p1301 [[nodiscard("should have a reason")]] + p1771 DR
|
||||
* tree.c (handle_nodiscard_attribute): Handle C++2a nodiscard
|
||||
string message.
|
||||
(std_attribute_table) Increase nodiscard argument handling
|
||||
max_length from 0 to 1.
|
||||
* parser.c (cp_parser_check_std_attribute): Add requirement
|
||||
that nodiscard only be seen once in attribute-list.
|
||||
(cp_parser_std_attribute): Check that empty parenthesis lists are
|
||||
not specified for attributes that have max_length > 0 (e.g.
|
||||
[[attr()]]).
|
||||
* cvt.c (maybe_warn_nodiscard): Add nodiscard message to
|
||||
output, if applicable.
|
||||
(convert_to_void): Allow constructors to be nodiscard-able (P1771).
|
||||
|
||||
2019-10-18 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* cp-tree.h (struct lang_type): Remove was_anonymous.
|
||||
|
|
36
gcc/cp/cvt.c
36
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);
|
||||
|
@ -1026,22 +1027,39 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
|
|||
|
||||
tree rettype = TREE_TYPE (type);
|
||||
tree fn = cp_get_fndecl_from_callee (callee);
|
||||
tree attr;
|
||||
if (implicit != ICV_CAST && fn
|
||||
&& lookup_attribute ("nodiscard", DECL_ATTRIBUTES (fn)))
|
||||
&& (attr = lookup_attribute ("nodiscard", DECL_ATTRIBUTES (fn))))
|
||||
{
|
||||
escaped_string msg;
|
||||
tree args = TREE_VALUE (attr);
|
||||
if (args)
|
||||
msg.escape (TREE_STRING_POINTER (TREE_VALUE (args)));
|
||||
const char* format = (msg ?
|
||||
G_("ignoring return value of %qD, "
|
||||
"declared with attribute %<nodiscard%>: %<%s%>") :
|
||||
G_("ignoring return value of %qD, "
|
||||
"declared with attribute %<nodiscard%>%s"));
|
||||
const char* raw_msg = msg ? msg : "";
|
||||
auto_diagnostic_group d;
|
||||
if (warning_at (loc, OPT_Wunused_result,
|
||||
"ignoring return value of %qD, "
|
||||
"declared with attribute nodiscard", fn))
|
||||
if (warning_at (loc, OPT_Wunused_result, format, fn, raw_msg))
|
||||
inform (DECL_SOURCE_LOCATION (fn), "declared here");
|
||||
}
|
||||
else if (implicit != ICV_CAST
|
||||
&& lookup_attribute ("nodiscard", TYPE_ATTRIBUTES (rettype)))
|
||||
&& (attr = lookup_attribute ("nodiscard", TYPE_ATTRIBUTES (rettype))))
|
||||
{
|
||||
escaped_string msg;
|
||||
tree args = TREE_VALUE (attr);
|
||||
if (args)
|
||||
msg.escape (TREE_STRING_POINTER (TREE_VALUE (args)));
|
||||
const char* format = msg ?
|
||||
G_("ignoring returned value of type %qT, "
|
||||
"declared with attribute %<nodiscard%>: %<%s%>") :
|
||||
G_("ignoring returned value of type %qT, "
|
||||
"declared with attribute %<nodiscard%>%s");
|
||||
const char* raw_msg = msg ? msg : "";
|
||||
auto_diagnostic_group d;
|
||||
if (warning_at (loc, OPT_Wunused_result,
|
||||
"ignoring returned value of type %qT, "
|
||||
"declared with attribute nodiscard", rettype))
|
||||
if (warning_at (loc, OPT_Wunused_result, format, rettype, raw_msg))
|
||||
{
|
||||
if (fn)
|
||||
inform (DECL_SOURCE_LOCATION (fn),
|
||||
|
@ -1180,7 +1198,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
|
|||
instantiations be affected by an ABI property that is, or at
|
||||
least ought to be transparent to the language. */
|
||||
if (tree fn = cp_get_callee_fndecl_nofold (expr))
|
||||
if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
|
||||
if (DECL_DESTRUCTOR_P (fn))
|
||||
return expr;
|
||||
|
||||
maybe_warn_nodiscard (expr, implicit);
|
||||
|
|
|
@ -26551,6 +26551,11 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
|
|||
arguments = error_mark_node;
|
||||
else
|
||||
{
|
||||
if (vec->is_empty())
|
||||
/* e.g. [[attr()]]. */
|
||||
error_at (token->location, "parentheses must be omitted if "
|
||||
"%qE attribute argument list is empty",
|
||||
attr_id);
|
||||
arguments = build_tree_list_vec (vec);
|
||||
release_tree_vector (vec);
|
||||
}
|
||||
|
@ -26565,9 +26570,9 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
|
|||
}
|
||||
|
||||
/* Check that the attribute ATTRIBUTE appears at most once in the
|
||||
attribute-list ATTRIBUTES. This is enforced for noreturn (7.6.3)
|
||||
and deprecated (7.6.5). Note that carries_dependency (7.6.4)
|
||||
isn't implemented yet in GCC. */
|
||||
attribute-list ATTRIBUTES. This is enforced for noreturn (7.6.3),
|
||||
nodiscard, and deprecated (7.6.5). Note that
|
||||
carries_dependency (7.6.4) isn't implemented yet in GCC. */
|
||||
|
||||
static void
|
||||
cp_parser_check_std_attribute (tree attributes, tree attribute)
|
||||
|
@ -26583,6 +26588,10 @@ cp_parser_check_std_attribute (tree attributes, tree attribute)
|
|||
&& lookup_attribute ("deprecated", attributes))
|
||||
error ("attribute %<deprecated%> can appear at most once "
|
||||
"in an attribute-list");
|
||||
else if (is_attribute_p ("nodiscard", name)
|
||||
&& lookup_attribute ("nodiscard", attributes))
|
||||
error ("attribute %<nodiscard%> can appear at most once "
|
||||
"in an attribute-list");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4369,9 +4369,14 @@ 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 && TREE_CODE (TREE_VALUE (args)) != STRING_CST)
|
||||
{
|
||||
error ("%qE attribute argument must be a string constant", name);
|
||||
*no_add_attrs = true;
|
||||
}
|
||||
if (TREE_CODE (*node) == FUNCTION_DECL)
|
||||
{
|
||||
if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (*node)))
|
||||
|
@ -4461,7 +4466,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 },
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_ESCAPED_STRING_H
|
||||
#define GCC_ESCAPED_STRING_H
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
/* 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 m_str; }
|
||||
void escape (const char *);
|
||||
private:
|
||||
escaped_string(const escaped_string&) {}
|
||||
escaped_string& operator=(const escaped_string&) { return *this; }
|
||||
char *m_str;
|
||||
bool m_owned;
|
||||
};
|
||||
|
||||
#endif /* ! GCC_ESCAPED_STRING_H */
|
|
@ -5,7 +5,7 @@
|
|||
[[noreturn(1)]] void f1 (); // { dg-error ".noreturn. attribute does not take any arguments" }
|
||||
[[noreturn(1, 2)]] void f2 (); // { dg-error ".noreturn. attribute does not take any arguments" }
|
||||
[[maybe_unused()]] int f3(); // { dg-error ".maybe_unused. attribute does not take any arguments" }
|
||||
[[nodiscard()]] int f4(); // { dg-error ".nodiscard. attribute does not take any arguments" }
|
||||
[[nodiscard()]] int f4(); // { dg-error "parentheses must be omitted if .nodiscard. attribute argument list is empty" }
|
||||
[[gnu::noinline()]] int f5(); // { dg-error ".noinline. attribute does not take any arguments" }
|
||||
[[gnu::constructor]] int f6();
|
||||
[[gnu::constructor(101)]] int f7(); // { dg-error "constructor priorities are not supported" "" { target { ! init_priority } } }
|
||||
|
|
|
@ -439,7 +439,7 @@
|
|||
|
||||
# if ! __has_cpp_attribute(nodiscard)
|
||||
# error "__has_cpp_attribute(nodiscard)"
|
||||
# elif __has_cpp_attribute(nodiscard) != 201603
|
||||
# elif (__has_cpp_attribute(nodiscard) != 201603 && __has_cpp_attribute(nodiscard) != 201907)
|
||||
# error "__has_cpp_attribute(nodiscard) != 201603"
|
||||
# endif
|
||||
|
||||
|
|
|
@ -470,8 +470,8 @@
|
|||
|
||||
# if ! __has_cpp_attribute(nodiscard)
|
||||
# error "__has_cpp_attribute(nodiscard)"
|
||||
# elif __has_cpp_attribute(nodiscard) != 201603
|
||||
# error "__has_cpp_attribute(nodiscard) != 201603"
|
||||
# elif __has_cpp_attribute(nodiscard) != 201907
|
||||
# error "__has_cpp_attribute(nodiscard) != 201907"
|
||||
# endif
|
||||
|
||||
# if ! __has_cpp_attribute(fallthrough)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/* nodiscard attribute tests */
|
||||
/* { dg-do compile { target c++2a } } */
|
||||
/* { dg-options "-O -ftrack-macro-expansion=0" } */
|
||||
|
||||
struct A { [[nodiscard("bad constructor")]] A() {} };
|
||||
struct B { [[nodiscard]] B() {} };
|
||||
|
||||
void
|
||||
test (void)
|
||||
{
|
||||
A{}; /* { dg-warning "(?n)nodiscard.*bad constructor" } */
|
||||
B{}; /* { dg-warning "(?n)nodiscard" } */
|
||||
}
|
|
@ -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 "(?n)nodiscard.*can appear at most once" } */
|
||||
|
||||
void
|
||||
test (void)
|
||||
{
|
||||
check1 ();
|
||||
(void) check1 ();
|
||||
}
|
|
@ -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 "(?n)nodiscard.*must be a string constant" } */
|
||||
|
||||
void
|
||||
test (void)
|
||||
{
|
||||
check1 ();
|
||||
(void) check1 ();
|
||||
}
|
|
@ -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 "(?n)wrong number of arguments..*nodiscard" } */
|
||||
|
||||
void
|
||||
test (void)
|
||||
{
|
||||
check1 ();
|
||||
(void) check1 ();
|
||||
}
|
|
@ -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 "(?n)10:.nodiscard.*exact_message" } */
|
||||
NODIS int foo; /* { dg-warning "(?n)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 "(?n)nodiscard.*exact_message" } */
|
||||
(void) check1 ();
|
||||
check1 (), bar (); /* { dg-warning "(?n)nodiscard.*exact_message" } */
|
||||
check2 ();
|
||||
(void) check2 ();
|
||||
check2 (), bar ();
|
||||
if (check3 ())
|
||||
return;
|
||||
i += check3 ();
|
||||
i += ({ check3 (); });
|
||||
check3 (); /* { dg-warning "(?n)nodiscard.*exact_inline_message" } */
|
||||
(void) check3 ();
|
||||
check3 (), bar (); /* { dg-warning "(?n)nodiscard.*exact_inline_message" } */
|
||||
a = check4 ();
|
||||
if (a.i)
|
||||
return;
|
||||
if (check4 ().i)
|
||||
return;
|
||||
if (({ check4 (); }).i)
|
||||
return;
|
||||
check4 (); /* { dg-warning "(?n)nodiscard.*exact_message" } */
|
||||
(void) check4 ();
|
||||
check4 (), bar (); /* { dg-warning "(?n)nodiscard.*exact_message" } */
|
||||
b = check5 ();
|
||||
if (b.i + b.j)
|
||||
return;
|
||||
if (check5 ().j)
|
||||
return;
|
||||
if (({ check5 (); }).j)
|
||||
return;
|
||||
check5 (); /* { dg-warning "(?n)nodiscard.*exact_message" } */
|
||||
(void) check5 ();
|
||||
check5 (), bar (); /* { dg-warning "(?n)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 "(?n)nodiscard.*exact_message" } */
|
||||
(void) check6 ();
|
||||
check6 (), bar (); /* { dg-warning "(?n)nodiscard.*exact_message" } */
|
||||
a = check7 ();
|
||||
if (a.i)
|
||||
return;
|
||||
if (check7 ().i)
|
||||
return;
|
||||
if (({ check7 (); }).i)
|
||||
return;
|
||||
check7 (); /* { dg-warning "(?n)nodiscard.*exact_inline_message" } */
|
||||
(void) check7 ();
|
||||
check7 (), bar (); /* { dg-warning "(?n)nodiscard.*exact_inline_message" } */
|
||||
b = check8 ();
|
||||
if (b.i + b.j)
|
||||
return;
|
||||
if (check8 ().j)
|
||||
return;
|
||||
if (({ check8 (); }).j)
|
||||
return;
|
||||
check8 (); /* { dg-warning "(?n)nodiscard.*exact_inline_message" } */
|
||||
(void) check8 ();
|
||||
check8 (), bar (); /* { dg-warning "(?n)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 "(?n)nodiscard.*exact_inline_message" } */
|
||||
(void) check9 ();
|
||||
check9 (), bar (); /* { dg-warning "(?n)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 "(?n)nodiscard.*exact_inline_message" } */
|
||||
(void) check_int_result (GU (j));
|
||||
check_int_result (GU (j)), bar (); /* { dg-warning "(?n)nodiscard.*exact_inline_message" } */
|
||||
if (fnptr ())
|
||||
return;
|
||||
i += fnptr ();
|
||||
i += ({ fnptr (); });
|
||||
fnptr (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
(void) fnptr ();
|
||||
fnptr (), bar (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
fnptr = check1;
|
||||
if (fnptr ())
|
||||
return;
|
||||
i += fnptr ();
|
||||
i += ({ fnptr (); });
|
||||
fnptr (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
(void) fnptr ();
|
||||
fnptr (), bar (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
fnptr = check3;
|
||||
if (fnptr ())
|
||||
return;
|
||||
i += fnptr ();
|
||||
i += ({ fnptr (); });
|
||||
fnptr (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
(void) fnptr ();
|
||||
fnptr (), bar (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
if (bar9 ().fn ())
|
||||
return;
|
||||
i += bar9 ().fn ();
|
||||
i += ({ bar9 ().fn (); });
|
||||
bar9 ().fn (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
(void) bar9 ().fn ();
|
||||
bar9 ().fn (), bar (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
if ((k ? check1 : check10) ())
|
||||
return;
|
||||
i += (k ? check1 : check10) ();
|
||||
i += ({ (k ? check1 : check10) (); });
|
||||
(k ? check1 : check10) (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
(void) (k ? check1 : check10) ();
|
||||
(k ? check1 : check10) (), bar (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
if ((k ? check3 : check11) ())
|
||||
return;
|
||||
i += (k ? check3 : check11) ();
|
||||
i += ({ (k ? check3 : check11) (); });
|
||||
(k ? check3 : check11) (); /* { dg-warning "(?n)nodiscard.*exact_inline_message" } */
|
||||
(void) (k ? check3 : check11) ();
|
||||
(k ? check3 : check11) (), bar (); /* { dg-warning "(?n)nodiscard.*exact_inline_message" } */
|
||||
if (pcheck1 ())
|
||||
return;
|
||||
i += pcheck1 ();
|
||||
i += ({ pcheck1 (); });
|
||||
pcheck1 (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
(void) pcheck1 ();
|
||||
pcheck1 (), bar (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
if (pcheck3 ())
|
||||
return;
|
||||
i += pcheck3 ();
|
||||
i += ({ pcheck3 (); });
|
||||
pcheck3 (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
(void) pcheck3 ();
|
||||
pcheck3 (), bar (); /* { dg-warning "(?n)nodiscard.*exact_E_message" } */
|
||||
d = check12 ();
|
||||
if (d.i)
|
||||
return;
|
||||
if (check12 ().i)
|
||||
return;
|
||||
if (({ check12 (); }).i)
|
||||
return;
|
||||
check12 (); /* { dg-warning "(?n)nodiscard.*exact_D_message" } */
|
||||
(void) check12 ();
|
||||
check12 (), bar (); /* { dg-warning "(?n)nodiscard.*exact_D_message" } */
|
||||
}
|
17
gcc/tree.c
17
gcc/tree.c
|
@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "regs.h"
|
||||
#include "tree-vector-builder.h"
|
||||
#include "gimple-fold.h"
|
||||
#include "escaped_string.h"
|
||||
|
||||
/* Tree code classes. */
|
||||
|
||||
|
@ -13225,22 +13226,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
|
||||
|
|
Loading…
Reference in New Issue