diff mbox

C/C++ OpenACC routine directive, undeclared name error: try to help the user, once

Message ID 877fejto7r.fsf@hertz.schwinge.homeip.net
State New
Headers show

Commit Message

Thomas Schwinge May 24, 2016, 4:28 p.m. UTC
Hi!

Some users of C/C++ OpenACC are surprised to see code such as:

    #pragma acc routine (F)
    [declaration or definition of F]

... run into "error: 'F' has not been declared".  If the routine
directive is meant to apply to the lexically following function
declaration or definition, either don't specify '(F)' here:

    #pragma acc routine
    [declaration or definition of F]

..., or place a function declaration before the directive:

    [declaration of F]
    #pragma acc routine (F)
    
    [definition or use of F]

OK for trunk?

commit 83442d8baef0d0c09128368879b69873cbf9bf01
Author: Thomas Schwinge <thomas@codesourcery.com>
Date:   Tue May 24 17:21:54 2016 +0200

    C/C++ OpenACC routine directive, undeclared name error: try to help the user, once
    
    	gcc/c/
    	* c-parser.c (c_parser_oacc_routine): If running into an
    	undeclared name error, try to help the user, once.
    	gcc/cp/
    	* parser.c (cp_parser_oacc_routine): If running into an undeclared
    	name error, try to help the user, once.
    	gcc/testsuite/
    	* c-c++-common/goacc/routine-5.c: Update.
---
 gcc/c/c-parser.c                             | 17 +++++++++++++++--
 gcc/cp/parser.c                              | 17 +++++++++++++++--
 gcc/testsuite/c-c++-common/goacc/routine-5.c | 15 ++++++++++++++-
 3 files changed, 44 insertions(+), 5 deletions(-)



Grüße
 Thomas

Comments

Nathan Sidwell May 31, 2016, 2:26 p.m. UTC | #1
On 05/24/16 12:28, Thomas Schwinge wrote:

> +	  static bool informed_once = false;
> +	  if (!informed_once)
> +	    {
> +	      inform (token->location,
> +		      "if the routine directive is meant to apply to the "
> +		      "lexically following function declaration or "
> +		      "definition, either don't specify %<(%E)%> here, or "
> +		      "place a function declaration before the directive",
> +		      id);
> +	      informed_once = true;

'lexically following' is implementor-speak.  This error message is for users who 
don't understand the difference between 'declaration' and 'use', so the wording 
should be simplified.   As the most common error is attempting to name the 
immediately following function, place that clue first.  I suggest
   "omit the %<(%E)%>, if you want to mark the immediately following function,
    or place this pragma after a declaration of the function to be marked"

nathan
diff mbox

Patch

diff --git gcc/c/c-parser.c gcc/c/c-parser.c
index cbd4e4c..6b589a4 100644
--- gcc/c/c-parser.c
+++ gcc/c/c-parser.c
@@ -13989,8 +13989,21 @@  c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
 	{
 	  decl = lookup_name (token->value);
 	  if (!decl)
-	    error_at (token->location, "%qE has not been declared",
-		      token->value);
+	    {
+	      error_at (token->location, "%qE has not been declared",
+			token->value);
+	      static bool informed_once = false;
+	      if (!informed_once)
+		{
+		  inform (token->location,
+			  "if the routine directive is meant to apply to the "
+			  "lexically following function declaration or "
+			  "definition, either don't specify %<(%E)%> here, or "
+			  "place a function declaration before the directive",
+			  token->value);
+		  informed_once = true;
+		}
+	    }
 	  c_parser_consume_token (parser);
 	}
       else
diff --git gcc/cp/parser.c gcc/cp/parser.c
index 6485cbd..4d542a0 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -36504,8 +36504,21 @@  cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok,
 					 /*optional_p=*/false);
       decl = cp_parser_lookup_name_simple (parser, id, token->location);
       if (id != error_mark_node && decl == error_mark_node)
-	cp_parser_name_lookup_error (parser, id, decl, NLE_NULL,
-				     token->location);
+	{
+	  cp_parser_name_lookup_error (parser, id, decl, NLE_NULL,
+				       token->location);
+	  static bool informed_once = false;
+	  if (!informed_once)
+	    {
+	      inform (token->location,
+		      "if the routine directive is meant to apply to the "
+		      "lexically following function declaration or "
+		      "definition, either don't specify %<(%E)%> here, or "
+		      "place a function declaration before the directive",
+		      id);
+	      informed_once = true;
+	    }
+	}
 
       if (decl == error_mark_node
 	  || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
diff --git gcc/testsuite/c-c++-common/goacc/routine-5.c gcc/testsuite/c-c++-common/goacc/routine-5.c
index 1efd154..9c30e87 100644
--- gcc/testsuite/c-c++-common/goacc/routine-5.c
+++ gcc/testsuite/c-c++-common/goacc/routine-5.c
@@ -71,7 +71,20 @@  void Foo ()
 
 #pragma acc routine (Foo) gang // { dg-error "must be applied before definition" }
 
-#pragma acc routine (Baz) // { dg-error "not been declared" }
+#pragma acc routine (Baz) worker
+/* { dg-error ".Baz. has not been declared" "" { target *-*-* } 74 }
+   Try to help the user:
+   { dg-message "note: if the routine directive" "" { target *-*-* } 74 } */
+
+#pragma acc routine (Baz) vector
+/* { dg-error ".Baz. has not been declared" "" { target *-*-* } 79 }
+   Don't try to help the user again:
+   { dg-bogus "note: if the routine directive" "" { target *-*-* } 79 } */
+
+#pragma acc routine (Qux) seq
+/* { dg-error ".Qux. has not been declared" "" { target *-*-* } 84 }
+   Don't try to help the user again:
+   { dg-bogus "note: if the routine directive" "" { target *-*-* } 84 } */
 
 
 int vb1;		/* { dg-error "directive for use" } */