public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] libstdc++/69116 Constrain std::valarray functions and operators
@ 2016-01-22 21:16 Jonathan Wakely
  2016-02-10 11:25 ` Jonathan Wakely
  0 siblings, 1 reply; 2+ messages in thread
From: Jonathan Wakely @ 2016-01-22 21:16 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1557 bytes --]

The example in the PR is a sneaky little problem. When <valarray> is
included the following overload is declared:

template<typename _Tp>
_Expr</* here be expression templates */>
operator<<(const _Tp& __t, const valarray<_Tp>& __v);

This is a candidate function for any "a << b" expression with
namespace std as an associated namespace. In order to do overload
resolution valarray<decltype(a)> gets instantiated to see if there is
a conversion from decltype(b). When decltype(a) is an abstract type
valarray<decltype(a)> results in an error outside the immediate
context, and overload resolution stops with an error.

This could happen for any of the overloaded operators and functions
that work with valarray, so my solution is to adjust the __fun<> class
template so that the result type of valarray operations is not defined
for types that cannot be used in valarray.  When the result_type is
missing the valarray operators give a SFINAE deduction failure not a
hard error.

Currently the check is !__is_abstract(_Tp) but it could be tweaked to
also check other conditions that cause a problem.

The new test uses -std=gnu++98 because if it uses a later standard
then it fails due to similar unconstrained operators in <complex>, and
std::complex<T> also fails if is_abstract<T>, so I'll have to fix that
next.

Tested powerpc64-linux, comimtted to trunk.

This is a regression, caused by the front end starting to diagnose the
invalid library instantiations more eagerly. The fix seems simple and
safe, so I plan to backport it to the branches too.



[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 3125 bytes --]

commit 64f205467ab5822f4b75f9ae14933c52d5062f66
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Jan 22 17:09:06 2016 +0000

    Constrain std::valarray functions and operators
    
    	PR libstdc++/69116
    	* include/bits/valarray_before.h (__fun, __fun_with_valarray): Only
    	define result_type for types which can be safely used with valarrays.
    	* testsuite/26_numerics/valarray/69116.cc: New.

diff --git a/libstdc++-v3/include/bits/valarray_before.h b/libstdc++-v3/include/bits/valarray_before.h
index 3325bf8..86136f4 100644
--- a/libstdc++-v3/include/bits/valarray_before.h
+++ b/libstdc++-v3/include/bits/valarray_before.h
@@ -331,14 +331,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return pow(__x, __y); }
   };
 
+  template<typename _Tp, bool _IsValidValarrayValue = !__is_abstract(_Tp)>
+    struct __fun_with_valarray
+    {
+      typedef _Tp result_type;
+    };
+
+  template<typename _Tp>
+    struct __fun_with_valarray<_Tp, false>
+    {
+      // No result type defined for invalid value types.
+    };
 
   // We need these bits in order to recover the return type of
   // some functions/operators now that we're no longer using
   // function templates.
   template<typename, typename _Tp>
-    struct __fun
+    struct __fun : __fun_with_valarray<_Tp>
     {
-      typedef _Tp result_type;
     };
 
   // several specializations for relational operators.
diff --git a/libstdc++-v3/testsuite/26_numerics/valarray/69116.cc b/libstdc++-v3/testsuite/26_numerics/valarray/69116.cc
new file mode 100644
index 0000000..ef98267
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/valarray/69116.cc
@@ -0,0 +1,53 @@
+// Copyright (C) 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/>.
+
+// { dg-do compile }
+// { dg-options "-std=gnu++98" }
+
+// libstdc++/69116
+
+#include <exception>
+#include <valarray>
+
+template<typename T>
+  void foo(const T&) { }
+
+struct X : std::exception // makes namespace std an associated namespace
+{
+  virtual void pure() = 0;
+
+  typedef void(*func_type)(const X&);
+
+  void operator+(func_type) const;
+  void operator-(func_type) const;
+  void operator*(func_type) const;
+  void operator/(func_type) const;
+  void operator%(func_type) const;
+  void operator<<(func_type) const;
+  void operator>>(func_type) const;
+};
+
+void foo(X& x)
+{
+  x + foo;
+  x - foo;
+  x * foo;
+  x / foo;
+  x % foo;
+  x << foo;
+  x >> foo;
+}

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [patch] libstdc++/69116 Constrain std::valarray functions and operators
  2016-01-22 21:16 [patch] libstdc++/69116 Constrain std::valarray functions and operators Jonathan Wakely
@ 2016-02-10 11:25 ` Jonathan Wakely
  0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2016-02-10 11:25 UTC (permalink / raw)
  To: libstdc++, gcc-patches

On 22/01/16 21:15 +0000, Jonathan Wakely wrote:
>This is a regression, caused by the front end starting to diagnose the
>invalid library instantiations more eagerly. The fix seems simple and
>safe, so I plan to backport it to the branches too.

Committed to the branches too.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-02-10 11:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-22 21:16 [patch] libstdc++/69116 Constrain std::valarray functions and operators Jonathan Wakely
2016-02-10 11:25 ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).