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]

[PATCH] libstdc++/77795 Only declare ::gets for C++98 and C++11


As noted in Bugzilla (and pointed out in LLVM's bugzilla by Richard
Smith) we check for a ::gets() declaration with the default
-std=gnu++14 mode, so for glibc we don't find it, and then we declare
it ourselves in <cstdio> even though it's not meant to exist in C++14.

This adjusts the check to use C++11, and doesn't declare it for C++14
and later. I think this fixes the regression, without introducing any
new problems.

Please take a look and double-check I haven't missed something.

	PR libstdc++/77795
	* acinclude.m4 (GLIBCXX_CHECK_STDIO_PROTO): Use -std=gnu++11 to check
	for gets.
	* config.h.in: Regenerate.
	* configure: Regenerate.
	* include/c_global/cstdio [!_GLIBCXX_HAVE_GETS] (gets): Only declare
	for C++98 and C++11.
	* include/c_std/cstdio [!_GLIBCXX_HAVE_GETS] (gets): Likewise.
	* testsuite/27_io/headers/cstdio/functions_neg.cc: New test.

I think we could also get rid of the hack in
config/os/gnu-linux/os_defines.h because it doesn't do anything:

// Provide a declaration for the possibly deprecated gets function, as
// glibc 2.15 and later does not declare gets for ISO C11 when
// __GNU_SOURCE is defined.
#if __GLIBC_PREREQ(2,15) && defined(_GNU_SOURCE)
# undef _GLIBCXX_HAVE_GETS
#endif

Firstly, neither 2.15 nor 2.16.0 has this issue (only some 2.15.xxx
versions built from version control rather than from official
releases). So we only need to check for exactly 2.15, rather than
anything >= 2.15.

Secondly, that file is included *before* c++config.h defines
_GLIBCXX_HAVE_GETS so the #undef doesn't work anyway. So I think we
might as well just get rid of it. If someone builds libstdc++ against
a 2.15.xxx without the gets declaration then we don't define
_GLIBCXX_HAVE_GETS and so we declare ::gets in <cstdio>.

If someone builds libstdc++ against 2.15 and then upgrades to a
glibc 2.15.xxx without gets they'll have problems, because
_GLIBCXX_HAVE_GETS will be defined to 1, but they won't have a gets
declaration in the glibc <stdio.h>. So don't do that. If we really
needed to we could support that by changing os_defines.h to:

#if __GLIBC__ == 2 && __GLIBC_MINOR__ == 15 && defined(_GNU_SOURCE)
# define _GLIBCXX_NEED_GETS_DECL
#endif

And then in <cstdio>:

#if __cplusplus <= 201103L
#if !defined(_GLIBCXX_HAVE_GETS) || defined(_GLIBCXX_NEED_GETS_DECL)
extern "C" char* gets (char* __s) __attribute__((__deprecated__));
#endif
#endif

But we haven't needed that until now, so I'd prefer to just drop the
hack in os_defines.h

commit fb65b330f57bf6b6e64fa3a7728e185ff4e45918
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Sep 30 10:26:35 2016 +0100

    libstdc++/77795 Only declare ::gets for C++98 and C++11
    
    	PR libstdc++/77795
    	* acinclude.m4 (GLIBCXX_CHECK_STDIO_PROTO): Use -std=gnu++11 to check
    	for gets.
    	* config.h.in: Regenerate.
    	* configure: Regenerate.
    	* include/c_global/cstdio [!_GLIBCXX_HAVE_GETS] (gets): Only declare
    	for C++98 and C++11.
    	* include/c_std/cstdio [!_GLIBCXX_HAVE_GETS] (gets): Likewise.
    	* testsuite/27_io/headers/cstdio/functions_neg.cc: New test.

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index ffead7d..d0ee45f 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2153,6 +2153,10 @@ AC_DEFUN([GLIBCXX_CHECK_STDIO_PROTO], [
 
   AC_LANG_SAVE
   AC_LANG_CPLUSPLUS
+  # Use C++11 because a conforming <stdio.h> won't define gets for C++14,
+  # and we don't need a declaration for C++14 anyway.
+  ac_save_CXXFLAGS="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAGS -std=gnu++11"
 
   AC_MSG_CHECKING([for gets declaration])
   AC_CACHE_VAL(glibcxx_cv_gets, [
@@ -2168,10 +2172,11 @@ AC_DEFUN([GLIBCXX_CHECK_STDIO_PROTO], [
       )])
 
   if test $glibcxx_cv_gets = yes; then
-    AC_DEFINE(HAVE_GETS, 1, [Define if gets is available in <stdio.h>.])
+    AC_DEFINE(HAVE_GETS, 1, [Define if gets is available in <stdio.h> before C++14.])
   fi
   AC_MSG_RESULT($glibcxx_cv_gets)
 
+  CXXFLAGS="$ac_save_CXXFLAGS"
   AC_LANG_RESTORE
 ])
 
diff --git a/libstdc++-v3/include/c_global/cstdio b/libstdc++-v3/include/c_global/cstdio
index 920d109..86d524f 100644
--- a/libstdc++-v3/include/c_global/cstdio
+++ b/libstdc++-v3/include/c_global/cstdio
@@ -44,7 +44,7 @@
 #ifndef _GLIBCXX_CSTDIO
 #define _GLIBCXX_CSTDIO 1
 
-#ifndef _GLIBCXX_HAVE_GETS
+#if __cplusplus <= 201103L && !defined(_GLIBCXX_HAVE_GETS)
 extern "C" char* gets (char* __s) __attribute__((__deprecated__));
 #endif
 
diff --git a/libstdc++-v3/include/c_std/cstdio b/libstdc++-v3/include/c_std/cstdio
index a4119ba..549004c 100644
--- a/libstdc++-v3/include/c_std/cstdio
+++ b/libstdc++-v3/include/c_std/cstdio
@@ -44,7 +44,7 @@
 #include <bits/c++config.h>
 #include <stdio.h>
 
-#ifndef _GLIBCXX_HAVE_GETS
+#if __cplusplus <= 201103L && !defined(_GLIBCXX_HAVE_GETS)
 extern "C" char* gets (char* __s) __attribute__((__deprecated__));
 #endif
 
diff --git a/libstdc++-v3/testsuite/27_io/headers/cstdio/functions_neg.cc b/libstdc++-v3/testsuite/27_io/headers/cstdio/functions_neg.cc
new file mode 100644
index 0000000..f9e5f86
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/headers/cstdio/functions_neg.cc
@@ -0,0 +1,25 @@
+// { dg-do compile  { target c++14 } }
+
+// Copyright (C) 2007-2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <cstdio>
+
+namespace gnu
+{
+  using std::gets; // { dg-error "has not been declared" }
+}

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