This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++] PATCH c++/18514
- From: Matt Austern <austern at apple dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 8 Dec 2004 16:06:15 -0800
- Subject: [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()