From c5b6f18e7a3d5a9269704287ca91483d60476e66 Mon Sep 17 00:00:00 2001
From: Mark Mitchell <mark@codesourcery.com>
Date: Sun, 29 Feb 2004 23:43:29 +0000
Subject: [PATCH] re PR middle-end/13448 (gcc 3.3.2, internal error when -O3
 and trying to modify function const arg)

	PR middle-end/13448
	* c-tree.h (readonly_warning): Rename to ...
	(readonly_error): ... this.
	* c-typeck.c (build_unary_op): Adjust accordingly.
	(readonly_warning): Rename to ...
	(readonly_error): ... this and issue errors, not warnings.
	(build_modify_expr): Call readonly_error, not readonly_warning.
	(c_expand_asm_operands): Likewise.
	* tree-inline.c (optimize_inline_calls): Do not inline functions
	after errors have occurred.

	PR middle-end/13448
	* gcc.dg/inline-5.c: New test.
	* gcc.dg/always-inline.c: Split out tests into ...
	* gcc.dg/always-inline2.c: ... this and ...
	* gcc.dg/always-inline3.c: ... this.

From-SVN: r78682
---
 gcc/ChangeLog                         | 13 +++++++++++++
 gcc/c-tree.h                          |  2 +-
 gcc/c-typeck.c                        | 26 +++++++++++++-------------
 gcc/testsuite/ChangeLog               |  8 ++++++++
 gcc/testsuite/gcc.dg/always_inline.c  | 12 ------------
 gcc/testsuite/gcc.dg/always_inline2.c |  8 ++++++++
 gcc/testsuite/gcc.dg/always_inline3.c |  8 ++++++++
 gcc/testsuite/gcc.dg/inline-5.c       | 13 +++++++++++++
 gcc/tree-inline.c                     |  8 +++++++-
 9 files changed, 71 insertions(+), 27 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/always_inline2.c
 create mode 100644 gcc/testsuite/gcc.dg/always_inline3.c
 create mode 100644 gcc/testsuite/gcc.dg/inline-5.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 833450837a37..6d0f8ce21a9b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2004-02-29  Mark Mitchell  <mark@codesourcery.com>
+
+	PR middle-end/13448
+	* c-tree.h (readonly_warning): Rename to ...
+	(readonly_error): ... this.
+	* c-typeck.c (build_unary_op): Adjust accordingly.
+	(readonly_warning): Rename to ...
+	(readonly_error): ... this and issue errors, not warnings.
+	(build_modify_expr): Call readonly_error, not readonly_warning.
+	(c_expand_asm_operands): Likewise.
+	* tree-inline.c (optimize_inline_calls): Do not inline functions
+	after errors have occurred.
+
 2004-02-29  Nathanael Nerode  <neroden@gcc.gnu.org>
 
 	* configure.ac: Rearrange some threading code for clarity;
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index 83592acc2f5c..6da67df0f2f5 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -268,7 +268,7 @@ extern tree build_array_ref (tree, tree);
 extern tree build_external_ref (tree, int);
 extern tree parser_build_binary_op (enum tree_code, tree, tree);
 extern int c_tree_expr_nonnegative_p (tree);
-extern void readonly_warning (tree, const char *);
+extern void readonly_error (tree, const char *);
 extern tree build_conditional_expr (tree, tree, tree);
 extern tree build_compound_expr (tree);
 extern tree c_cast_expr (tree, tree);
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 8ad4400ede1d..ffb4468af2ac 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -2387,10 +2387,10 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
 
 	/* Report a read-only lvalue.  */
 	if (TREE_READONLY (arg))
-	  readonly_warning (arg,
-			    ((code == PREINCREMENT_EXPR
-			      || code == POSTINCREMENT_EXPR)
-			     ? "increment" : "decrement"));
+	  readonly_error (arg,
+			  ((code == PREINCREMENT_EXPR
+			    || code == POSTINCREMENT_EXPR)
+			   ? "increment" : "decrement"));
 
 	if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
 	  val = boolean_increment (code, arg);
@@ -2545,21 +2545,21 @@ lvalue_or_else (tree ref, const char *msgid)
 /* Warn about storing in something that is `const'.  */
 
 void
-readonly_warning (tree arg, const char *msgid)
+readonly_error (tree arg, const char *msgid)
 {
   if (TREE_CODE (arg) == COMPONENT_REF)
     {
       if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
-	readonly_warning (TREE_OPERAND (arg, 0), msgid);
+	readonly_error (TREE_OPERAND (arg, 0), msgid);
       else
-	pedwarn ("%s of read-only member `%s'", _(msgid),
-		 IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
+	error ("%s of read-only member `%s'", _(msgid),
+	       IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
     }
   else if (TREE_CODE (arg) == VAR_DECL)
-    pedwarn ("%s of read-only variable `%s'", _(msgid),
-	     IDENTIFIER_POINTER (DECL_NAME (arg)));
+    error ("%s of read-only variable `%s'", _(msgid),
+	   IDENTIFIER_POINTER (DECL_NAME (arg)));
   else
-    pedwarn ("%s of read-only location", _(msgid));
+    error ("%s of read-only location", _(msgid));
 }
 
 /* Mark EXP saying that we need to be able to take the
@@ -3142,7 +3142,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
       || ((TREE_CODE (lhstype) == RECORD_TYPE
 	   || TREE_CODE (lhstype) == UNION_TYPE)
 	  && C_TYPE_FIELDS_READONLY (lhstype)))
-    readonly_warning (lhs, "assignment");
+    readonly_error (lhs, "assignment");
 
   /* If storing into a structure or union member,
      it has probably been given type `int'.
@@ -6149,7 +6149,7 @@ c_expand_asm_operands (tree string, tree outputs, tree inputs,
 	      || ((TREE_CODE (type) == RECORD_TYPE
 		   || TREE_CODE (type) == UNION_TYPE)
 		  && C_TYPE_FIELDS_READONLY (type)))
-	    readonly_warning (o[i], "modification by `asm'");
+	    readonly_error (o[i], "modification by `asm'");
 	}
     }
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b5aa29d32f2c..74be633db116 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2004-02-29  Mark Mitchell  <mark@codesourcery.com>
+
+	PR middle-end/13448
+	* gcc.dg/inline-5.c: New test.
+	* gcc.dg/always-inline.c: Split out tests into ...
+	* gcc.dg/always-inline2.c: ... this and ...
+	* gcc.dg/always-inline3.c: ... this.
+
 2004-02-29  Mark Mitchell  <mark@codesourcery.com>
 
 	PR debug/12103
diff --git a/gcc/testsuite/gcc.dg/always_inline.c b/gcc/testsuite/gcc.dg/always_inline.c
index 9480470a95af..2177f642f606 100644
--- a/gcc/testsuite/gcc.dg/always_inline.c
+++ b/gcc/testsuite/gcc.dg/always_inline.c
@@ -1,18 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-Winline -O2" } */
 #include <stdarg.h>
-inline __attribute__ ((always_inline)) void t(void); /* { dg-error "body not available" "" } */
-void
-q(void)
-{
-  t(); 				/* { dg-error "called from here" "" } */
-}
-inline __attribute__ ((always_inline)) void
-q2(void)
-{ 				/* { dg-error "recursive" "" } */
-  q2(); 			/* { dg-error "called from here" "" } */
-  q2(); 			/* { dg-error "called from here" "" } */
-}
 inline __attribute__ ((always_inline)) void
 e(int t, ...)
 {				/* { dg-error "variable argument" "" } */
diff --git a/gcc/testsuite/gcc.dg/always_inline2.c b/gcc/testsuite/gcc.dg/always_inline2.c
new file mode 100644
index 000000000000..fa6528d1fac1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/always_inline2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-Winline -O2" } */
+inline __attribute__ ((always_inline)) void t(void); /* { dg-error "body not available" "" } */
+void
+q(void)
+{
+  t(); 				/* { dg-error "called from here" "" } */
+}
diff --git a/gcc/testsuite/gcc.dg/always_inline3.c b/gcc/testsuite/gcc.dg/always_inline3.c
new file mode 100644
index 000000000000..b183770adc00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/always_inline3.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-Winline -O2" } */
+inline __attribute__ ((always_inline)) void
+q2(void)
+{ 				/* { dg-error "recursive" "" } */
+  q2(); 			/* { dg-error "called from here" "" } */
+  q2(); 			/* { dg-error "called from here" "" } */
+}
diff --git a/gcc/testsuite/gcc.dg/inline-5.c b/gcc/testsuite/gcc.dg/inline-5.c
new file mode 100644
index 000000000000..d72fad656100
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/inline-5.c
@@ -0,0 +1,13 @@
+/* PR middle-end/13448 */
+
+/* { dg-options "-O3" } */
+
+void funct (const int n)
+{
+  n++; /* { dg-error "" } */
+}
+
+int main () {
+  funct (1);
+  return 0;
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 3ef97051ebc0..ba5eb7ab0554 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -39,7 +39,7 @@ Boston, MA 02111-1307, USA.  */
 #include "langhooks.h"
 #include "cgraph.h"
 #include "intl.h"
-
+#include "diagnostic.h"
 
 /* This should be eventually be generalized to other languages, but
    this would require a shared function-as-trees infrastructure.  */
@@ -1620,6 +1620,12 @@ optimize_inline_calls (tree fn)
   inline_data id;
   tree prev_fn;
 
+  /* There is no point in performing inlining if errors have already
+     occurred -- and we might crash if we try to inline invalid
+     code.  */
+  if (errorcount || sorrycount)
+    return;
+
   /* Clear out ID.  */
   memset (&id, 0, sizeof (id));
 
-- 
GitLab