OSDN Git Service

* typeck.c (decay_conversion): Don't confuse constant array
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Feb 1999 12:15:37 +0000 (12:15 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Feb 1999 12:15:37 +0000 (12:15 +0000)
variables with their intiailizers.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25459 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.other/string1.C [new file with mode: 0644]

index 4424a32..34e8ef8 100644 (file)
@@ -1,5 +1,8 @@
 1999-02-26  Mark Mitchell  <mark@markmitchell.com>
 
+       * typeck.c (decay_conversion): Don't confuse constant array
+       variables with their intiailizers.
+
        * decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when
        merging decls.
        * pt.c (regenerate_decl_from_template): Tweak for clarity.
index 426d02b..9a99097 100644 (file)
@@ -1589,12 +1589,11 @@ c_alignof (type)
   return t;
 }
 \f
-/* Perform default promotions for C data used in expressions.
-   Arrays and functions are converted to pointers;
-   enumeral types or short or char, to int.
-   In addition, manifest constants symbols are replaced by their values.
+/* Perform the array-to-pointer and function-to-pointer conversions
+   for EXP.  
 
-   C++: this will automatically bash references to their target type.  */
+   In addition, references are converted to rvalues and manifest
+   constants are replaced by their values.  */
 
 tree
 decay_conversion (exp)
@@ -1628,8 +1627,15 @@ decay_conversion (exp)
   /* Constants can be used directly unless they're not loadable.  */
   if (TREE_CODE (exp) == CONST_DECL)
     exp = DECL_INITIAL (exp);
-  /* Replace a nonvolatile const static variable with its value.  */
-  else if (TREE_READONLY_DECL_P (exp))
+  /* Replace a nonvolatile const static variable with its value.  We
+     don't do this for arrays, though; we want the address of the
+     first element of the array, not the address of the first element
+     of its initializing constant.  We *do* replace variables that the
+     user isn't really supposed to know about; this is a hack to deal
+     with __PRETTY_FUNCTION__ and the like.  */
+  else if (TREE_READONLY_DECL_P (exp)
+          && (code != ARRAY_TYPE 
+              || (TREE_CODE (exp) == VAR_DECL && DECL_IGNORED_P (exp))))
     {
       exp = decl_constant_value (exp);
       type = TREE_TYPE (exp);
@@ -1649,9 +1655,7 @@ decay_conversion (exp)
       return build_unary_op (ADDR_EXPR, exp, 0);
     }
   if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
-    {
-      return build_unary_op (ADDR_EXPR, exp, 0);
-    }
+    return build_unary_op (ADDR_EXPR, exp, 0);
   if (code == ARRAY_TYPE)
     {
       register tree adr;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/string1.C b/gcc/testsuite/g++.old-deja/g++.other/string1.C
new file mode 100644 (file)
index 0000000..425e9bf
--- /dev/null
@@ -0,0 +1,20 @@
+// Build don't link:
+// Origin: mrs@wrs.com (Mike Stump)
+
+class Wrapper {
+public:
+  static const char msgPtr[];
+  static const char *JunkFunc() {
+    return &msgPtr[0];
+  }
+};
+const char Wrapper::msgPtr[] = "Hello world.";
+int main() {
+  const char *p1 = &Wrapper::msgPtr[0];
+  const char *p2 = Wrapper::JunkFunc();
+  if (p1 != p2)
+    return 1;
+}