2015-11-19  Nathan Sidwell  <nathan@acm.org>

	gcc/
	* config/nvptx/nvptx.h (SUPPORTS_WEAK): Define.
	* config/nvptx/nvptx.c (nvptx_write_function_decl): Support
	DECL_WEAK.
	(nvptx_declare_objec_name): Likewise.

	gcc/testsuite/
	* lib/target-supports.exp (check_weak_available): Add nvptx-*-*.
	* gcc.dg/attr-weakref-1.c: Skip for nvptx-*-*
	* gcc.dg/special/weak-2.c: Likewise.
	* gcc.dg/weak/weak-12.c: Likewise.
	* gcc.dg/weak/weak-15.c: Likewise.
	* gcc.dg/weak/weak-16.c: Likewise.
	* gcc.dg/weak/weak-1.c: Likewise.
	* gcc.dg/weak/weak-2.c: Likewise.
	* gcc.dg/weak/weak-4.c: Likewise.
	* gcc.dg/torture/pr53922.c: Likewise.
	* gcc.dg/torture/pr60092.c: Likewise.

Index: config/nvptx/nvptx.c
===================================================================
--- config/nvptx/nvptx.c	(revision 230554)
+++ config/nvptx/nvptx.c	(working copy)
@@ -379,7 +379,7 @@ nvptx_write_function_decl (std::stringst
   if (DECL_EXTERNAL (decl))
     s << ".extern ";
   else if (TREE_PUBLIC (decl))
-    s << ".visible ";
+    s << (DECL_WEAK (decl) ? ".weak " : ".visible ");
 
   if (kernel)
     s << ".entry ";
@@ -1780,8 +1780,9 @@ nvptx_declare_object_name (FILE *file, c
       size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
       const char *section = nvptx_section_for_decl (decl);
       fprintf (file, "\t%s%s .align %d .u%d ",
-	       TREE_PUBLIC (decl) ? " .visible" : "", section,
-	       DECL_ALIGN (decl) / BITS_PER_UNIT,
+	       !TREE_PUBLIC (decl) ? ""
+	       : DECL_WEAK (decl) ? ".weak" : ".visible",
+	       section, DECL_ALIGN (decl) / BITS_PER_UNIT,
 	       decl_chunk_size * BITS_PER_UNIT);
       assemble_name (file, name);
       if (size > 0)
Index: config/nvptx/nvptx.h
===================================================================
--- config/nvptx/nvptx.h	(revision 230554)
+++ config/nvptx/nvptx.h	(working copy)
@@ -349,6 +349,7 @@ struct GTY(()) machine_function
 #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
   ((VALUE) = GET_MODE_BITSIZE ((MODE)), 2)
 
+#define SUPPORTS_WEAK 1
 #define NO_DOT_IN_LABEL
 #define ASM_COMMENT_START "//"
 
Index: testsuite/lib/target-supports.exp
===================================================================
--- testsuite/lib/target-supports.exp	(revision 230554)
+++ testsuite/lib/target-supports.exp	(working copy)
@@ -292,6 +292,12 @@ proc check_weak_available { } {
 	return 0
     }
 
+    # nvptx (nearly) supports it
+
+    if { [istarget nvptx-*-*] } {
+	return 1
+    }
+
     # ELF and ECOFF support it. a.out does with gas/gld but may also with
     # other linkers, so we should try it
 
Index: testsuite/gcc.dg/attr-weakref-1.c
===================================================================
--- testsuite/gcc.dg/attr-weakref-1.c	(revision 230554)
+++ testsuite/gcc.dg/attr-weakref-1.c	(working copy)
@@ -1,10 +1,12 @@
 // { dg-do run }
 // { dg-require-weak "" }
 // On darwin, we use attr-weakref-1-darwin.c.
+
 // This test requires support for undefined weak symbols.  This support
-// is not available on hppa*-*-hpux*.  The test is skipped rather than
+// is not available on the following targets.  The test is skipped rather than
 // xfailed to suppress the warning that would otherwise arise.
-// { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" } "*" { "" } }
+// { dg-skip-if "" { "hppa*-*-hpux*" "*-*-aix*" "nvptx-*-*" } "*" { "" } }
+
 // For kernel modules and static RTPs, the loader treats undefined weak
 // symbols in the same way as undefined strong symbols.  The test
 // therefore fails to load, so skip it.
Index: testsuite/gcc.dg/special/weak-2.c
===================================================================
--- testsuite/gcc.dg/special/weak-2.c	(revision 230554)
+++ testsuite/gcc.dg/special/weak-2.c	(working copy)
@@ -2,6 +2,10 @@
 /* { dg-require-weak "" } */
 /* { dg-additional-sources "weak-2a.c weak-2b.c" } */
 
+/* NVPTX's implementation of weak is broken when a strong symbol is in
+   a later object file than the weak definition.   */
+/* { dg-skip-if "" { "nvptx-*-*" } "*" { "" } } */
+
 #include <stdlib.h>
 
 extern int foo(void);
Index: testsuite/gcc.dg/weak/weak-12.c
===================================================================
--- testsuite/gcc.dg/weak/weak-12.c	(revision 230554)
+++ testsuite/gcc.dg/weak/weak-12.c	(working copy)
@@ -2,6 +2,8 @@
 /* { dg-do compile } */
 /* { dg-require-weak "" } */
 /* { dg-options "" } */
+/* NVPTX's weak is applied to the definition,  not declaration.  */
+/* { dg-skip-if "" { nvptx-*-* } { "*" } { "" } } */
 
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?foo" } } */
 
Index: testsuite/gcc.dg/weak/weak-15.c
===================================================================
--- testsuite/gcc.dg/weak/weak-15.c	(revision 230554)
+++ testsuite/gcc.dg/weak/weak-15.c	(working copy)
@@ -2,6 +2,8 @@
 /* { dg-require-weak "" } */
 /* { dg-options "-fno-common" } */
 /* { dg-skip-if "" { x86_64-*-mingw* } { "*" } { "" } } */
+/* NVPTX's weak is applied to the definition,  not declaration.  */
+/* { dg-skip-if "" { nvptx-*-* } { "*" } { "" } } */
 
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?a" } } */
 /* { dg-final { scan-assembler-not "weak\[^ \t\]*\[ \t\]_?b" } } */
Index: testsuite/gcc.dg/weak/weak-16.c
===================================================================
--- testsuite/gcc.dg/weak/weak-16.c	(revision 230554)
+++ testsuite/gcc.dg/weak/weak-16.c	(working copy)
@@ -5,6 +5,8 @@
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?kallsyms_token_index" } } */
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?kallsyms_token_table" } } */
 /* { dg-skip-if "" { x86_64-*-mingw* } { "*" } { "" } } */
+/* NVPTX's weak is applied to the definition,  not declaration.  */
+/* { dg-skip-if "" { nvptx-*-* } { "*" } { "" } } */
 
 extern int kallsyms_token_index[] __attribute__((weak));
 extern int kallsyms_token_table[] __attribute__((weak));
Index: testsuite/gcc.dg/weak/weak-1.c
===================================================================
--- testsuite/gcc.dg/weak/weak-1.c	(revision 230554)
+++ testsuite/gcc.dg/weak/weak-1.c	(working copy)
@@ -2,6 +2,8 @@
 /* { dg-require-weak "" } */
 /* { dg-options "-fno-common" } */
 /* { dg-skip-if "" { *-*-mingw* } { "*" } { "" } } */
+/* NVPTX's definition of weak looks different to normal.  */
+/* { dg-skip-if "" { nvptx-*-* } { "*" } { "" } } */
 
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?a" } } */
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?b" } } */
Index: testsuite/gcc.dg/weak/weak-2.c
===================================================================
--- testsuite/gcc.dg/weak/weak-2.c	(revision 230554)
+++ testsuite/gcc.dg/weak/weak-2.c	(working copy)
@@ -2,6 +2,8 @@
 /* { dg-require-weak "" } */
 /* { dg-options "-fno-common" } */
 /* { dg-skip-if "" { x86_64-*-mingw* } { "*" } { "" } } */
+/* NVPTX's definition of weak looks different to normal.  */
+/* { dg-skip-if "" { nvptx-*-* } { "*" } { "" } } */
 
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?ffoo1a" } } */
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?ffoo1b" } } */
Index: testsuite/gcc.dg/weak/weak-4.c
===================================================================
--- testsuite/gcc.dg/weak/weak-4.c	(revision 230554)
+++ testsuite/gcc.dg/weak/weak-4.c	(working copy)
@@ -2,6 +2,8 @@
 /* { dg-require-weak "" } */
 /* { dg-options "-fno-common" } */
 /* { dg-skip-if "" { x86_64-*-mingw* } { "*" } { "" } } */
+/* NVPTX's definition of weak looks different to normal.  */
+/* { dg-skip-if "" { nvptx-*-* } { "*" } { "" } } */
 
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1a" } } */
 /* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?vfoo1b" } } */
Index: testsuite/gcc.dg/torture/pr53922.c
===================================================================
--- testsuite/gcc.dg/torture/pr53922.c	(revision 230554)
+++ testsuite/gcc.dg/torture/pr53922.c	(working copy)
@@ -3,6 +3,7 @@
 /* { dg-skip-if "No undefined" { *-*-mingw* } { "*" } { "" } } */
 /* { dg-skip-if "No undefined weak" { *-*-aix* } { "*" } { "" } } */
 /* { dg-skip-if "No undefined weak" { hppa*-*-hpux* && { ! lp64 } } { "*" } { "" } } */
+/* { dg-skip-if "No undefined weak" { nvptx-*-* } { "*" } { "" } } */
 /* { dg-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
 /* { dg-additional-options "-Wl,-flat_namespace" { target *-*-darwin[89]* } } */
 
Index: testsuite/gcc.dg/torture/pr60092.c
===================================================================
--- testsuite/gcc.dg/torture/pr60092.c	(revision 230554)
+++ testsuite/gcc.dg/torture/pr60092.c	(working copy)
@@ -1,6 +1,7 @@
 /* { dg-do run } */
 /* { dg-require-weak "" } */
 /* { dg-skip-if "No undefined weak" { hppa*-*-hpux* && { ! lp64 } } } */
+/* { dg-skip-if "No undefined weak" { nvptx-*-* } { "*" } { "" } } */
 /* { dg-additional-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
 /* { dg-additional-options "-Wl,-flat_namespace" { target *-*-darwin[89]* } } */
 /* { dg-xfail-run-if "posix_memalign modifies first arg on error" { *-*-solaris2.11* } { "-O0" } } */
