Movatterモバイル変換
[0]ホーム
This is the mail archive of thelibc-alpha@sourceware.orgmailing list for theglibc project.
Re: [PATCH] assert: Support types without operator== (int) [BZ #21972]
On 08/18/2017 07:30 PM, Paul Eggert wrote:> Florian Weimer wrote:>>> Florian Weimer wrote:>>>> + ((void) sizeof (static_cast<bool> (expr)), __extension__ ({ \>>> Can we instead replace 'sizeof ((expr) == 0)' with 'sizeof !(expr)'?>>> That works in C, and if it also works in C++ it would avoid the need>>> for the #ifdef __cplusplus.>> It does not work in C++ because operator! could have been overloaded>> or deleted.> > OK, then how about 'sizeof ((expr) ? 1 : 0)'? This should work because> ?: cannot be overloaded.Oh, this works. Updated patch attached.Thanks,Florianassert: Support types without operator== (int) [BZ #21972]2017-08-18 Florian Weimer <fweimer@redhat.com>[BZ #21972]* assert/assert.h (assert): Use static_cast (bool) for C++ in thepedantic warning check, to avoid a requirement for operator== (int).* assert/Makefile (tests): Add tst-assert-c++, tst-assert-g++.(CFLAGS-tst-assert-c++.o): Compile in C++11 mode.(CFLAGS-tst-assert-g++.o): Compile in GnU C++11 mode.(LDLIBS-tst-assert-c++, LDLIBS-tst-assert-g++): Link with libstdc++.* assert/tst-assert-c++.cc, assert/tst-assert-g++.cc: New files.diff --git a/assert/Makefile b/assert/Makefileindex 1c3be9b01f..9ec1be81a9 100644--- a/assert/Makefile+++ b/assert/Makefile@@ -25,6 +25,15 @@ include ../Makeconfig headers:= assert.h routines := assert assert-perr __assert-tests := test-assert test-assert-perr+tests := test-assert test-assert-perr tst-assert-c++ tst-assert-g++ include ../Rules++ifeq ($(have-cxx-thread_local),yes)+CFLAGS-tst-assert-c++.o = -std=c++11+LDLIBS-tst-assert-c++ = -lstdc+++CFLAGS-tst-assert-g++.o = -std=gnu++11+LDLIBS-tst-assert-g++ = -lstdc+++else+tests-unsupported += tst-assert-c++ tst-assert-g+++endifdiff --git a/assert/assert.h b/assert/assert.hindex 6801cfeb10..0ce99e06c8 100644--- a/assert/assert.h+++ b/assert/assert.h@@ -93,12 +93,11 @@ __END_DECLS # else /* The first occurrence of EXPR is not evaluated due to the sizeof, but will trigger any pedantic warnings masked by the __extension__- for the second occurrence. The explicit comparison against zero is- required to support function pointers and bit fields in this- context, and to suppress the evaluation of variable length- arrays. */+ for the second occurrence. The ternary operator is required to+ support function pointers and bit fields in this context, and to+ suppress the evaluation of variable length arrays. */ # define assert(expr)\- ((void) sizeof ((expr) == 0), __extension__ ({\+ ((void) sizeof ((expr) ? 1 : 0), __extension__ ({\ if (expr)\ ; /* empty */\ else\diff --git a/assert/tst-assert-c++.cc b/assert/tst-assert-c++.ccnew file mode 100644index 0000000000..c001bfff49--- /dev/null+++ b/assert/tst-assert-c++.cc@@ -0,0 +1,72 @@+/* Tests for interactions between C++ and assert.+ Copyright (C) 2017 Free Software Foundation, Inc.+ This file is part of the GNU C Library.++ The GNU C Library is free software; you can redistribute it and/or+ modify it under the terms of the GNU Lesser General Public+ License as published by the Free Software Foundation; either+ version 2.1 of the License, or (at your option) any later version.++ The GNU C 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+ Lesser General Public License for more details.++ You should have received a copy of the GNU Lesser General Public+ License along with the GNU C Library; if not, see+ <http://www.gnu.org/licenses/>. */++#include <assert.h>++/* The C++ standard requires that if the assert argument is a constant+ subexpression, then the assert itself is one, too. */+constexpr int+check_constexpr ()+{+ return (assert (true), 1);+}++/* Objects of this class can be contextually converted to bool, but+ cannot be compared to int. */+struct no_int+{+ no_int () = default;+ no_int (const no_int &) = delete;++ explicit operator bool () const+ {+ return true;+ }+};++/* This class tests that operator== is not used by assert. */+struct bool_and_int+{+ bool_and_int () = default;+ bool_and_int (const no_int &) = delete;++ explicit operator bool () const+ {+ return true;+ }++ template <class T> bool operator== (T) const; /* No definition. */+};++static int+do_test ()+{+ {+ no_int value;+ assert (value);+ }++ {+ bool_and_int value;+ assert (value);+ }++ return 0;+}++#include <support/test-driver.c>diff --git a/assert/tst-assert-g++.cc b/assert/tst-assert-g++.ccnew file mode 100644index 0000000000..8c06402825--- /dev/null+++ b/assert/tst-assert-g++.cc@@ -0,0 +1,19 @@+/* Tests for interactions between C++ and assert. GNU C++11 version.+ Copyright (C) 2017 Free Software Foundation, Inc.+ This file is part of the GNU C Library.++ The GNU C Library is free software; you can redistribute it and/or+ modify it under the terms of the GNU Lesser General Public+ License as published by the Free Software Foundation; either+ version 2.1 of the License, or (at your option) any later version.++ The GNU C 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+ Lesser General Public License for more details.++ You should have received a copy of the GNU Lesser General Public+ License along with the GNU C Library; if not, see+ <http://www.gnu.org/licenses/>. */++#include <tst-assert-c++.cc>
[8]ページ先頭