This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++] PATCH c++/18514


This patch changes builtin handling so that using-declarations don't interfere with giving a builtin an alternate "asm" name. (Yes, pr 18514 is a somewhat obscure corner case, but it's one that has come up in practice.) Various test cases included, to make sure that I'm not breaking any other obscure corner cases that involve builtin.

Note that I've made a change in one of the libstdc++ test cases. I've traced through the code, and I believe that test case was just plain wrong: it used "malloc" without a declaration being present. If it ever worked, I think it can only have been by accident.

OK to commit to mainline?

--Matt

* name-lookup.c (do_nonmember_using_decl): A real function declaration takes precedence over an anticipated declaration.

* ext/builtin1.C: New.
* ext/builtin2.C: New.
* ext/builtin3.C: New.
* ext/builtin4.C: New.
* ext/builtin5.C: New.

* ext/malloc_allocator.h: Make sure we see a declaration of malloc.


Index: gcc/cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.100
diff -p -r1.100 name-lookup.c
*** gcc/cp/name-lookup.c 7 Dec 2004 14:41:12 -0000 1.100
--- gcc/cp/name-lookup.c 8 Dec 2004 23:43:02 -0000
*************** do_nonmember_using_decl (tree scope, tre
*** 2064,2073 ****
are the same extern "C" functions, that's ok. */
if (decls_match (new_fn, old_fn))
{
! /* If the OLD_FN was a builtin, there is now a
! real declaration. */
if (DECL_ANTICIPATED (old_fn))
! DECL_ANTICIPATED (old_fn) = 0;
break;
}
else if (!DECL_ANTICIPATED (old_fn))
--- 2064,2079 ----
are the same extern "C" functions, that's ok. */
if (decls_match (new_fn, old_fn))
{
! /* If the OLD_FN was a builtin, we've seen a real
! declaration in another namespace. Use it instead.
! Set tmp1 to NULL so we can use the existing
! OVERLOAD logic at the end of this inner loop.
! */
if (DECL_ANTICIPATED (old_fn))
! {
! gcc_assert (! DECL_ANTICIPATED (new_fn));
! tmp1 = NULL;
! }
break;
}
else if (!DECL_ANTICIPATED (old_fn))
Index: gcc/testsuite/g++.dg/ext/builtin1.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin1.C
diff -N gcc/testsuite/g++.dg/ext/builtin1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin1.C 8 Dec 2004 23:43:04 -0000
***************
*** 0 ****
--- 1,10 ----
+ // Test whether alternate 'asm' name is applied correctly to
+ // builtin in global namespace
+
+ // { dg-do compile }
+ // { dg-options "" }
+ // { dg-final { scan-assembler "fancy_printf" } }
+
+ extern "C" int printf(char*, ...) __asm("_fancy_printf");
+
+ void foo() { printf("abc"); }
Index: gcc/testsuite/g++.dg/ext/builtin2.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin2.C
diff -N gcc/testsuite/g++.dg/ext/builtin2.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin2.C 8 Dec 2004 23:43:04 -0000
***************
*** 0 ****
--- 1,13 ----
+ // PR c++/18514
+ // Test whether alternate 'asm' name is applied correctly to
+ // builtin imported into namespace std.
+
+ // { dg-do compile }
+ // { dg-options "" }
+ // { dg-final { scan-assembler "fancy_printf" } }
+
+ extern "C" int printf(char*, ...) __asm("_fancy_printf");
+
+ namespace std { using ::printf; }
+
+ namespace std { void foo() { printf("abc"); } }
Index: gcc/testsuite/g++.dg/ext/builtin3.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin3.C
diff -N gcc/testsuite/g++.dg/ext/builtin3.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin3.C 8 Dec 2004 23:43:04 -0000
***************
*** 0 ****
--- 1,13 ----
+ // Verify that declaring builtin in namespace std doesn't give us
+ // declaration in global namespace
+
+ // { dg-do compile }
+ // { dg-options "" }
+
+ namespace std {
+ extern "C" int printf(char*, ...);
+ }
+
+ void foo() {
+ printf("abc"); // { dg-error "not declared" }
+ }
Index: gcc/testsuite/g++.dg/ext/builtin4.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin4.C
diff -N gcc/testsuite/g++.dg/ext/builtin4.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin4.C 8 Dec 2004 23:43:04 -0000
***************
*** 0 ****
--- 1,10 ----
+ // Verify that builtin is used when declared in global namespace
+
+ // { dg-do compile }
+ // { dg-options "-Wall" }
+
+ extern "C" int printf(const char*,...);
+
+ void foo() {
+ printf("%d"); // { dg-warning "too few arguments" }
+ }
Index: gcc/testsuite/g++.dg/ext/builtin5.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin5.C
diff -N gcc/testsuite/g++.dg/ext/builtin5.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin5.C 8 Dec 2004 23:43:04 -0000
***************
*** 0 ****
--- 1,12 ----
+ // Verify that builtin is used when declared in namespace std
+
+ // { dg-do compile }
+ // { dg-options "-Wall" }
+
+ namespace std {
+ extern "C" int printf(const char*,...);
+ }
+
+ void foo() {
+ std::printf("%d"); // { dg-warning "too few arguments" }
+ }
Index: libstdc++-v3/include/ext/malloc_allocator.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/ext/malloc_allocator.h,v
retrieving revision 1.12
diff -p -r1.12 malloc_allocator.h
*** libstdc++-v3/include/ext/malloc_allocator.h 5 Dec 2004 00:25:18 -0000 1.12
--- libstdc++-v3/include/ext/malloc_allocator.h 8 Dec 2004 23:43:17 -0000
***************
*** 36,41 ****
--- 36,42 ----


  #include <cstdlib>
  #include <new>
+ #include <cstdlib>
  #include <bits/functexcept.h>

  namespace __gnu_cxx
*************** namespace __gnu_cxx
*** 86,92 ****
  	if (__builtin_expect(__n > this->max_size(), false))
  	  std::__throw_bad_alloc();

! 	pointer __ret = static_cast<_Tp*>(malloc(__n * sizeof(_Tp)));
  	if (!__ret)
  	  std::__throw_bad_alloc();
  	return __ret;
--- 87,93 ----
  	if (__builtin_expect(__n > this->max_size(), false))
  	  std::__throw_bad_alloc();

! 	pointer __ret = static_cast<_Tp*>(std::malloc(__n * sizeof(_Tp)));
  	if (!__ret)
  	  std::__throw_bad_alloc();
  	return __ret;
*************** namespace __gnu_cxx
*** 95,101 ****
        // __p is not permitted to be a null pointer.
        void
        deallocate(pointer __p, size_type)
!       { free(static_cast<void*>(__p)); }

        size_type
        max_size() const throw()
--- 96,102 ----
        // __p is not permitted to be a null pointer.
        void
        deallocate(pointer __p, size_type)
!       { std::free(static_cast<void*>(__p)); }

        size_type
        max_size() const throw()


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]