From: David Malcolm <dmalcolm@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: Martin Sebor <msebor@gmail.com>,
Eric Gallager <egall@gwmail.gwu.edu>,
gcc-patches List <gcc-patches@gcc.gnu.org>,
David Malcolm <dmalcolm@redhat.com>
Subject: [PATCH] v3: C/C++: add fix-it hints for missing '&' and '*' (PR c++/87850)
Date: Mon, 19 Nov 2018 21:23:00 -0000 [thread overview]
Message-ID: <1542662581-41571-1-git-send-email-dmalcolm@redhat.com> (raw)
In-Reply-To: <CADzB+2nMUVXThn=8_CeurHmCo2Rckqy+37RuEYBSFNqsCkY20Q@mail.gmail.com>
On Fri, 2018-11-16 at 13:13 -0500, Jason Merrill wrote:
> On Thu, Nov 15, 2018 at 4:48 PM David Malcolm <dmalcolm@redhat.com>
> wrote:
> > On Tue, 2018-11-13 at 16:34 -0500, Jason Merrill wrote:
> > > On Mon, Nov 12, 2018 at 4:32 PM Martin Sebor <msebor@gmail.com>
> > > wrote:
> > > > On 11/11/2018 02:02 PM, David Malcolm wrote:
> > > > > On Sun, 2018-11-11 at 11:01 -0700, Martin Sebor wrote:
> > > > > > On 11/10/2018 12:01 AM, Eric Gallager wrote:
> > > > > > > On 11/9/18, David Malcolm <dmalcolm@redhat.com> wrote:
> > > > > > > > This patch adds a fix-it hint to various pointer-vs-
> > > > > > > > non-
> > > > > > > > pointer
> > > > > > > > diagnostics, suggesting the addition of a leading '&'
> > > > > > > > or
> > > > > > > > '*'.
> > > > > > > >
> > > > > > > > For example, note the ampersand fix-it hint in the
> > > > > > > > following:
> > > > > > > >
> > > > > > > > demo.c:5:22: error: invalid conversion from
> > > > > > > > 'pthread_key_t'
> > > > > > > > {aka
> > > > > > > > 'unsigned
> > > > > > > > int'}
> > > > > > > > to 'pthread_key_t*' {aka 'unsigned int*'} [-
> > > > > > > > fpermissive]
> > > > > > > > 5 | pthread_key_create(key, NULL);
> > > > > > > > | ^~~
> > > > > > > > | |
> > > > > > > > | pthread_key_t {aka
> > > > > > > > unsigned
> > > > > > > > int}
> > > > > > > > | &
> > > > > > >
> > > > > > > Having both the type and the fixit underneath the caret
> > > > > > > looks
> > > > > > > kind
> > > > > > > of confusing
> > > > > >
> > > > > > I agree it's rather subtle. Keeping the diagnostics
> > > > > > separate
> > > > > > from
> > > > > > the suggested fix should avoid the confusion.
> > > > >
> > > > > FWIW, the fix-it hint is in a different color (assuming that
> > > > > gcc
> > > > > is
> > > > > invoked in an environment that prints that...)
> > > >
> > > > I figured it would be, but I'm still not sure it's good design
> > > > to be relying on color alone to distinguish between the problem
> > > > and the suggested fix. Especially when they are so close to
> > > > one
> > > > another and the fix is just a single character with no obvious
> > > > relationship to the rest of the text on the screen. In other
> > > > warnings there's at least the "did you forget the '@'?" part
> > > > to give a clue, even though even there the connection between
> > > > the "did you forget" and the & several lines down wouldn't
> > > > necessarily be immediately apparent.
> > >
> > > Agreed, something along those lines would help to understand why
> > > the
> > > compiler is throwing a random & into the diagnostic.
> > >
> > > Jason
> >
> > Here's an updated version which adds a note, putting the fix-it
> > hint
> > on that instead (I attempted adding the text to the initial error,
> > but there was something of a combinatorial explosion of messages).
> >
> > The above example becomes:
> >
> > demo.c: In function 'int main()':
> > demo.c:5:22: error: invalid conversion from 'pthread_key_t' {aka
> > 'unsigned int'}
> > to 'pthread_key_t*' {aka 'unsigned int*'} [-fpermissive]
> > 5 | pthread_key_create(key, NULL);
> > | ^~~
> > | |
> > | pthread_key_t {aka unsigned int}
> > demo.c:5:22: note: possible fix: take the address with '&'
> > 5 | pthread_key_create(key, NULL);
> > | ^~~
> > | &
> > In file included from demo.c:1:
> > /usr/include/pthread.h:1122:47: note: initializing argument 1 of
> > 'int pthread_key_create(pthread_key_t*, void (*)(void*))'
> > 1122 | extern int pthread_key_create (pthread_key_t *__key,
> > | ~~~~~~~~~~~~~~~^~~~~
> >
> > Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
> >
> > OK for trunk?
> >
> > gcc/c-family/ChangeLog:
> > PR c++/87850
> > * c-common.c: Include "gcc-rich-location.h".
> > (maybe_emit_indirection_note): New function.
> > * c-common.h (maybe_emit_indirection_note): New decl.
> >
> > gcc/c/ChangeLog:
> > PR c++/87850
> > * c-typeck.c (convert_for_assignment): Call
> > maybe_emit_indirection_note for pointer vs non-pointer
> > diagnostics.
> >
> > gcc/cp/ChangeLog:
> > PR c++/87850
> > * call.c (convert_like_real): Call
> > maybe_emit_indirection_note for "invalid conversion"
> > diagnostic.
> >
> > gcc/testsuite/ChangeLog:
> > PR c++/87850
> > * c-c++-common/indirection-fixits.c: New test.
> > ---
> > gcc/c-family/c-common.c | 33 +++
> > gcc/c-family/c-common.h | 2 +
> > gcc/c/c-typeck.c | 10 +-
> > gcc/cp/call.c | 2 +
> > gcc/testsuite/c-c++-common/indirection-fixits.c | 270
> > ++++++++++++++++++++++++
> > 5 files changed, 315 insertions(+), 2 deletions(-)
> > create mode 100644 gcc/testsuite/c-c++-common/indirection-fixits.c
> >
> > diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
> > index cd88f3a..d5c7c7f 100644
> > --- a/gcc/c-family/c-common.c
> > +++ b/gcc/c-family/c-common.c
> > @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not
> > see
> > #include "gimplify.h"
> > #include "substring-locations.h"
> > #include "spellcheck.h"
> > +#include "gcc-rich-location.h"
> > #include "selftest.h"
> >
> > cpp_reader *parse_in; /* Declared in c-pragma.h. */
> > @@ -8405,6 +8406,38 @@ maybe_suggest_missing_token_insertion
> > (rich_location *richloc,
> > }
> > }
> >
> > +/* Potentially emit a note about likely missing '&' or '*',
> > + depending on EXPR and EXPECTED_TYPE. */
> > +
> > +void
> > +maybe_emit_indirection_note (location_t loc,
> > + tree expr, tree expected_type)
> > +{
> > + gcc_assert (expr);
> > + gcc_assert (expected_type);
> > +
> > + tree actual_type = TREE_TYPE (expr);
> > +
> > + /* Missing '&'. */
> > + if (TREE_CODE (expected_type) == POINTER_TYPE
> > + && actual_type == TREE_TYPE (expected_type)
>
> Type comparison should use same_type_p, not ==, so that we deal
> properly with typedef variants. OK with that change.
>
> Jason
The above code is in c-family, but same_type_p is specific to C++,
so the change is not quite trivial.
Here's a v3 of the patch which moves same_type_p from cp/cp-tree.h
to c-family/c-common.h, converting it from a macro to an extern decl,
with implementations for C and for C++. I used:
comptypes (type1, type2) == 1
for the C implementation of same_type_p.
The v3 patch uses same_type_p rather than pointer equality, and I added
a test case for a typedef of int vs a int.
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Is this OK for trunk?
Thanks
Dave
gcc/c-family/ChangeLog:
PR c++/87850
* c-common.c: Include "gcc-rich-location.h".
(maybe_emit_indirection_note): New function.
* c-common.h (maybe_emit_indirection_note): New decl.
(same_type_p): New decl
gcc/c/ChangeLog:
PR c++/87850
* c-typeck.c (same_type_p): New function.
(convert_for_assignment): Call maybe_emit_indirection_note for
pointer vs non-pointer diagnostics.
gcc/cp/ChangeLog:
PR c++/87850
* call.c (convert_like_real): Call
maybe_emit_indirection_note for "invalid conversion" diagnostic.
* cp-tree.h (same_type_p): Delete macro, moving to...
* typeck.c (same_type_p): New function.
gcc/testsuite/ChangeLog:
PR c++/87850
* c-c++-common/indirection-fixits.c: New test.
---
gcc/c-family/c-common.c | 33 +++
gcc/c-family/c-common.h | 4 +
gcc/c/c-typeck.c | 20 +-
gcc/cp/call.c | 2 +
gcc/cp/cp-tree.h | 5 -
gcc/cp/typeck.c | 10 +
gcc/testsuite/c-c++-common/indirection-fixits.c | 299 ++++++++++++++++++++++++
7 files changed, 366 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/c-c++-common/indirection-fixits.c
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index cd88f3a..babe329 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h"
#include "substring-locations.h"
#include "spellcheck.h"
+#include "gcc-rich-location.h"
#include "selftest.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
@@ -8405,6 +8406,38 @@ maybe_suggest_missing_token_insertion (rich_location *richloc,
}
}
+/* Potentially emit a note about likely missing '&' or '*',
+ depending on EXPR and EXPECTED_TYPE. */
+
+void
+maybe_emit_indirection_note (location_t loc,
+ tree expr, tree expected_type)
+{
+ gcc_assert (expr);
+ gcc_assert (expected_type);
+
+ tree actual_type = TREE_TYPE (expr);
+
+ /* Missing '&'. */
+ if (TREE_CODE (expected_type) == POINTER_TYPE
+ && same_type_p (actual_type, TREE_TYPE (expected_type))
+ && lvalue_p (expr))
+ {
+ gcc_rich_location richloc (loc);
+ richloc.add_fixit_insert_before ("&");
+ inform (&richloc, "possible fix: take the address with %qs", "&");
+ }
+
+ /* Missing '*'. */
+ if (TREE_CODE (actual_type) == POINTER_TYPE
+ && same_type_p (TREE_TYPE (actual_type), expected_type))
+ {
+ gcc_rich_location richloc (loc);
+ richloc.add_fixit_insert_before ("*");
+ inform (&richloc, "possible fix: dereference with %qs", "*");
+ }
+}
+
#if CHECKING_P
namespace selftest {
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 31cc273..e0be104 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1340,8 +1340,12 @@ extern void maybe_add_include_fixit (rich_location *, const char *, bool);
extern void maybe_suggest_missing_token_insertion (rich_location *richloc,
enum cpp_ttype token_type,
location_t prev_token_loc);
+extern void maybe_emit_indirection_note (location_t loc,
+ tree expr, tree expected_type);
extern tree braced_list_to_string (tree, tree);
+extern bool same_type_p (tree type1, tree type2);
+
#if CHECKING_P
namespace selftest {
/* Declarations for specific families of tests within c-family,
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 5d4e973..1ddcf71 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -1003,6 +1003,16 @@ common_type (tree t1, tree t2)
return c_common_type (t1, t2);
}
+/* C implementation of same_type_p.
+ Returns true iff TYPE1 and TYPE2 are the same type, in the usual
+ sense of `same'. */
+
+bool
+same_type_p (tree type1, tree type2)
+{
+ return comptypes (type1, type2) == 1;
+}
+
/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
or various other operations. Return 2 if they are compatible
but a warning may be needed if you use them together. */
@@ -7061,7 +7071,10 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
if (pedwarn (&richloc, OPT_Wint_conversion,
"passing argument %d of %qE makes pointer from "
"integer without a cast", parmnum, rname))
- inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
+ {
+ maybe_emit_indirection_note (expr_loc, rhs, type);
+ inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
+ }
}
break;
case ic_assign:
@@ -7097,7 +7110,10 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
if (pedwarn (&richloc, OPT_Wint_conversion,
"passing argument %d of %qE makes integer from "
"pointer without a cast", parmnum, rname))
- inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
+ {
+ maybe_emit_indirection_note (expr_loc, rhs, type);
+ inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
+ }
}
break;
case ic_assign:
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ee099cc..a25d109 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6862,6 +6862,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
complained = permerror (&richloc,
"invalid conversion from %qH to %qI",
TREE_TYPE (expr), totype);
+ if (complained)
+ maybe_emit_indirection_note (loc, expr, totype);
}
if (complained && fn)
inform (get_fndecl_argument_location (fn, argnum),
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f2e6709..57d9eed 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -671,11 +671,6 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
#define REINTERPRET_CAST_P(NODE) \
TREE_LANG_FLAG_0 (NOP_EXPR_CHECK (NODE))
-/* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual
- sense of `same'. */
-#define same_type_p(TYPE1, TYPE2) \
- comptypes ((TYPE1), (TYPE2), COMPARE_STRICT)
-
/* Returns nonzero iff NODE is a declaration for the global function
`main'. */
#define DECL_MAIN_P(NODE) \
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 7b42d53..eeae9f1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1448,6 +1448,16 @@ structural_comptypes (tree t1, tree t2, int strict)
return comp_type_attributes (t1, t2);
}
+/* C++ implementation of same_type_p.
+ Returns true iff TYPE1 and TYPE2 are the same type, in the usual
+ sense of `same'. */
+
+bool
+same_type_p (tree type1, tree type2)
+{
+ return comptypes (type1, type2, COMPARE_STRICT);
+}
+
/* Return true if T1 and T2 are related as allowed by STRICT. STRICT
is a bitwise-or of the COMPARE_* flags. */
diff --git a/gcc/testsuite/c-c++-common/indirection-fixits.c b/gcc/testsuite/c-c++-common/indirection-fixits.c
new file mode 100644
index 0000000..8987ee9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/indirection-fixits.c
@@ -0,0 +1,299 @@
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+void takes_int_ptr(int*);
+void takes_char_ptr(char*);
+void takes_int(int);
+int returns_int(void);
+
+int ivar;
+char cvar;
+int *int_ptr;
+char *char_ptr;
+
+void test_1 (void)
+{
+ takes_int_ptr(&ivar);
+ takes_int_ptr(int_ptr);
+ takes_char_ptr(&cvar);
+ takes_char_ptr(char_ptr);
+
+ ivar = 42;
+ cvar = 'b';
+ int_ptr = &ivar;
+ char_ptr = &cvar;
+}
+
+void test_2 (void)
+{
+ takes_int_ptr(ivar); /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+ /* { dg-message "possible fix: take the address with '&'" "" { target *-*-* } .-2 } */
+
+ /* Expect an '&' fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ takes_int_ptr(ivar);
+ ^~~~
+ |
+ int
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ takes_int_ptr(ivar);
+ ^~~~
+ &
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ void takes_int_ptr(int*);
+ ^~~~
+ { dg-end-multiline-output "" } */
+}
+
+void test_3 (void)
+{
+ takes_int_ptr(cvar); /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+
+ /* Don't expect an '&' fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ takes_int_ptr(cvar);
+ ^~~~
+ |
+ char
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ void takes_int_ptr(int*);
+ ^~~~
+ { dg-end-multiline-output "" } */
+}
+
+void test_4 (void)
+{
+ takes_char_ptr(ivar); /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+
+ /* Don't expect an '&' fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ takes_char_ptr(ivar);
+ ^~~~
+ |
+ int
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ void takes_char_ptr(char*);
+ ^~~~~
+ { dg-end-multiline-output "" } */
+}
+
+void test_5 (void)
+{
+ takes_char_ptr(cvar); /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+
+ /* Expect an '&' fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ takes_char_ptr(cvar);
+ ^~~~
+ |
+ char
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ takes_char_ptr(cvar);
+ ^~~~
+ &
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ void takes_char_ptr(char*);
+ ^~~~~
+ { dg-end-multiline-output "" } */
+}
+
+void test_6 (void)
+{
+ takes_int(int_ptr); /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+ /* { dg-message "possible fix: dereference with '*'" "" { target *-*-* } .-2 } */
+
+ /* Expect a '*' fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ takes_int(int_ptr);
+ ^~~~~~~
+ |
+ int *
+ { dg-end-multiline-output "" { target c } } */
+ /* { dg-begin-multiline-output "" }
+ takes_int(int_ptr);
+ ^~~~~~~
+ |
+ int*
+ { dg-end-multiline-output "" { target c++ } } */
+ /* { dg-begin-multiline-output "" }
+ takes_int(int_ptr);
+ ^~~~~~~
+ *
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ void takes_int(int);
+ ^~~
+ { dg-end-multiline-output "" } */
+}
+
+void test_7 (void)
+{
+ takes_int(char_ptr); /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+
+ /* Don't expect a '*' fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ takes_int(char_ptr);
+ ^~~~~~~~
+ |
+ char *
+ { dg-end-multiline-output "" { target c } } */
+ /* { dg-begin-multiline-output "" }
+ takes_int(char_ptr);
+ ^~~~~~~~
+ |
+ char*
+ { dg-end-multiline-output "" { target c++ } } */
+ /* { dg-begin-multiline-output "" }
+ void takes_int(int);
+ ^~~
+ { dg-end-multiline-output "" } */
+}
+
+void test_8 (void)
+{
+ ivar = int_ptr; /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+
+ /* Expect a fix-it hint from the C++ FE, but not from C (due to missing
+ location). */
+ /* { dg-begin-multiline-output "" }
+ ivar = int_ptr;
+ ^~~~~~~
+ |
+ int*
+ { dg-end-multiline-output "" { target c++ } } */
+ /* { dg-begin-multiline-output "" }
+ ivar = int_ptr;
+ ^~~~~~~
+ *
+ { dg-end-multiline-output "" { target c++ } } */
+ /* { dg-begin-multiline-output "" }
+ ivar = int_ptr;
+ ^
+ { dg-end-multiline-output "" { target c } } */
+}
+
+void test_9 (void)
+{
+ cvar = int_ptr; /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+
+ /* Don't expect a '*' fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ cvar = int_ptr;
+ ^~~~~~~
+ |
+ int*
+ { dg-end-multiline-output "" { target c++ } } */
+ /* { dg-begin-multiline-output "" }
+ cvar = int_ptr;
+ ^
+ { dg-end-multiline-output "" { target c } } */
+}
+
+void test_10 (void)
+{
+ int_ptr = ivar; /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+
+ /* Expect a fix-it hint from the C++ FE, but not from C (due to missing
+ location). */
+ /* { dg-begin-multiline-output "" }
+ int_ptr = ivar;
+ ^~~~
+ |
+ int
+ { dg-end-multiline-output "" { target c++ } } */
+ /* { dg-begin-multiline-output "" }
+ int_ptr = ivar;
+ ^~~~
+ &
+ { dg-end-multiline-output "" { target c++ } } */
+ /* { dg-begin-multiline-output "" }
+ int_ptr = ivar;
+ ^
+ { dg-end-multiline-output "" { target c } } */
+}
+
+void test_11 (void)
+{
+ char_ptr = ivar; /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+
+ /* Don't expect a fix-it hint, due to mismatching types. */
+ /* { dg-begin-multiline-output "" }
+ char_ptr = ivar;
+ ^~~~
+ |
+ int
+ { dg-end-multiline-output "" { target c++ } } */
+ /* { dg-begin-multiline-output "" }
+ char_ptr = ivar;
+ ^
+ { dg-end-multiline-output "" { target c } } */
+}
+
+/* We shouldn't offer '&' fix-it hints for non-lvalues. */
+
+void test_12 (void)
+{
+ takes_int_ptr (returns_int ()); /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+
+ /* { dg-begin-multiline-output "" }
+ takes_int_ptr (returns_int ());
+ ^~~~~~~~~~~~~~
+ |
+ int
+ { dg-end-multiline-output "" { target c } } */
+ /* { dg-begin-multiline-output "" }
+ takes_int_ptr (returns_int ());
+ ~~~~~~~~~~~~^~
+ |
+ int
+ { dg-end-multiline-output "" { target c++ } } */
+ /* { dg-begin-multiline-output "" }
+ void takes_int_ptr(int*);
+ ^~~~
+ { dg-end-multiline-output "" } */
+}
+
+/* Ignore typedefs when offering fix-it hints. */
+
+typedef int typedef_int_t;
+typedef_int_t typedef_int_t_var;
+
+void test_13 (void)
+{
+ takes_int_ptr (typedef_int_t_var); /* { dg-warning "" "" { target c } } */
+ /* { dg-error "" "" { target c++ } .-1 } */
+ /* { dg-message "possible fix: take the address with '&'" "" { target *-*-* } .-2 } */
+
+ /* Expect an '&' fix-it hint. */
+ /* { dg-begin-multiline-output "" }
+ takes_int_ptr (typedef_int_t_var);
+ ^~~~~~~~~~~~~~~~~
+ |
+ typedef_int_t {aka int}
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ takes_int_ptr (typedef_int_t_var);
+ ^~~~~~~~~~~~~~~~~
+ &
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ void takes_int_ptr(int*);
+ ^~~~
+ { dg-end-multiline-output "" } */
+}
--
1.8.5.3
next prev parent reply other threads:[~2018-11-19 21:23 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-09 22:36 [PATCH] " David Malcolm
2018-11-10 7:01 ` Eric Gallager
2018-11-11 18:01 ` Martin Sebor
2018-11-11 21:02 ` David Malcolm
2018-11-12 21:32 ` Martin Sebor
2018-11-13 21:34 ` Jason Merrill
2018-11-15 21:48 ` [PATCH] v2: " David Malcolm
2018-11-16 18:13 ` Jason Merrill
2018-11-19 21:23 ` David Malcolm [this message]
2018-11-20 2:46 ` [PATCH] v3: " Joseph Myers
2018-11-20 22:05 ` David Malcolm
2018-11-20 22:23 ` Joseph Myers
2018-11-30 23:01 ` [PATCH] v4: " David Malcolm
2018-12-01 18:38 ` Jason Merrill
2018-12-03 22:14 ` Joseph Myers
2018-12-05 16:03 ` Jason Merrill
2018-12-05 16:18 ` David Malcolm
2018-11-21 0:36 ` [PATCH] v3: " Jeff Law
2018-11-21 0:39 ` Martin Sebor
2018-11-30 15:27 ` David Malcolm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1542662581-41571-1-git-send-email-dmalcolm@redhat.com \
--to=dmalcolm@redhat.com \
--cc=egall@gwmail.gwu.edu \
--cc=gcc-patches@gcc.gnu.org \
--cc=jason@redhat.com \
--cc=msebor@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).