r343761 - [constexpr] Fix ICE when memcpy() is given a pointer to an incomplete array
Author: petr.pavlu Date: Thu Oct 4 02:25:44 2018 New Revision: 343761 URL: http://llvm.org/viewvc/llvm-project?rev=343761&view=rev Log: [constexpr] Fix ICE when memcpy() is given a pointer to an incomplete array Fix code for constant evaluation of __builtin_memcpy() and __builtin_memmove() that would attempt to divide by zero when given two pointers to an incomplete array. Differential Revision: https://reviews.llvm.org/D51855 Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/test/CodeGen/builtin-memfns.c cfe/trunk/test/SemaCXX/constexpr-string.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=343761&r1=343760&r2=343761&view=diff == --- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Thu Oct 4 02:25:44 2018 @@ -173,6 +173,9 @@ def note_constexpr_memcpy_type_pun : Not def note_constexpr_memcpy_nontrivial : Note< "cannot constant evaluate '%select{memcpy|memmove}0' between objects of " "non-trivially-copyable type %1">; +def note_constexpr_memcpy_incomplete_type : Note< + "cannot constant evaluate '%select{memcpy|memmove}0' between objects of " + "incomplete type %1">; def note_constexpr_memcpy_overlap : Note< "'%select{memcpy|wmemcpy}0' between overlapping memory regions">; def note_constexpr_memcpy_unsupported : Note< Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=343761&r1=343760&r2=343761&view=diff == --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Oct 4 02:25:44 2018 @@ -6239,6 +6239,10 @@ bool PointerExprEvaluator::VisitBuiltinC Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << SrcT << T; return false; } +if (T->isIncompleteType()) { + Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) << Move << T; + return false; +} if (!T.isTriviallyCopyableType(Info.Ctx)) { Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) << Move << T; return false; Modified: cfe/trunk/test/CodeGen/builtin-memfns.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-memfns.c?rev=343761&r1=343760&r2=343761&view=diff == --- cfe/trunk/test/CodeGen/builtin-memfns.c (original) +++ cfe/trunk/test/CodeGen/builtin-memfns.c Thu Oct 4 02:25:44 2018 @@ -111,3 +111,10 @@ void test11() { memcpy(&d, (char *)&e.a, sizeof(e)); } +// CHECK-LABEL: @test12 +extern char dest_array[]; +extern char src_array[]; +void test12() { + // CHECK: call void @llvm.memcpy{{.*}}( + memcpy(&dest_array, &dest_array, 2); +} Modified: cfe/trunk/test/SemaCXX/constexpr-string.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-string.cpp?rev=343761&r1=343760&r2=343761&view=diff == --- cfe/trunk/test/SemaCXX/constexpr-string.cpp (original) +++ cfe/trunk/test/SemaCXX/constexpr-string.cpp Thu Oct 4 02:25:44 2018 @@ -387,4 +387,41 @@ namespace MemcpyEtc { // designators until we have a long enough matching size, if both designators // point to the start of their respective final elements. static_assert(test_derived_to_base(2) == 3434); // expected-error {{constant}} expected-note {{in call}} + + // Check that when address-of an array is passed to a tested function the + // array can be fully copied. + constexpr int test_address_of_const_array_type() { +int arr[4] = {1, 2, 3, 4}; +__builtin_memmove(&arr, &arr, sizeof(arr)); +return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3]; + } + static_assert(test_address_of_const_array_type() == 1234); + + // Check that an incomplete array is rejected. + constexpr int test_incomplete_array_type() { // expected-error {{never produces a constant}} +extern int arr[]; +__builtin_memmove(arr, arr, 4 * sizeof(arr[0])); +// expected-note@-1 2{{'memmove' not supported: source is not a contiguous array of at least 4 elements of type 'int'}} +return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3]; + } + static_assert(test_incomplete_array_type() == 1234); // expected-error {{constant}} expected-note {{in call}} + + // Check that a pointer to an incomplete array is rejected. + constexpr int test_address_of_incomplete_array_type() { // expected-error {{never produces a constant}} +extern int arr[]; +__builtin_memmove(&arr, &arr, 4 * sizeof(arr[0])); +// expected-note@-1 2{{cannot constant evaluate 'memmove' between objects of incomple
r330507 - [libclang] Fix LibclangReparseTest.FileName when TMPDIR is set to a symlink
Author: petr.pavlu Date: Sat Apr 21 07:35:18 2018 New Revision: 330507 URL: http://llvm.org/viewvc/llvm-project?rev=330507&view=rev Log: [libclang] Fix LibclangReparseTest.FileName when TMPDIR is set to a symlink Fix testing of clang_File_tryGetRealPathName() in LibclangReparseTest.FileName when executing in an environment which has TMPDIR set to a symbolic link that points to an actual directory. The test would fail because the name returned by clang_File_tryGetRealPathName() has the symlink resolved but the test compared it to the original filename of a temporary file. The patch addresses the problem by checking only that the value returned by clang_File_tryGetRealPathName() ends with "main.cpp". Additionally, the patch makes the previous assertion in the test that checks result of clang_getFileName() stricter. It newly verifies that the name returned by the function is exactly same as what was given to clang_parseTranslationUnit()/clang_getFile(). Differential Revision: https://reviews.llvm.org/D45807 Modified: cfe/trunk/unittests/libclang/LibclangTest.cpp Modified: cfe/trunk/unittests/libclang/LibclangTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/libclang/LibclangTest.cpp?rev=330507&r1=330506&r2=330507&view=diff == --- cfe/trunk/unittests/libclang/LibclangTest.cpp (original) +++ cfe/trunk/unittests/libclang/LibclangTest.cpp Sat Apr 21 07:35:18 2018 @@ -8,6 +8,7 @@ //===--===// #include "clang-c/Index.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" @@ -490,11 +491,11 @@ TEST_F(LibclangReparseTest, FileName) { CXFile cxf = clang_getFile(ClangTU, CppName.c_str()); CXString cxname = clang_getFileName(cxf); - ASSERT_TRUE(strstr(clang_getCString(cxname), CppName.c_str())); + ASSERT_STREQ(clang_getCString(cxname), CppName.c_str()); clang_disposeString(cxname); cxname = clang_File_tryGetRealPathName(cxf); - ASSERT_TRUE(strstr(clang_getCString(cxname), CppName.c_str())); + ASSERT_TRUE(llvm::StringRef(clang_getCString(cxname)).endswith("main.cpp")); clang_disposeString(cxname); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r336842 - Fix setting of empty implicit-section-name attribute
Author: petr.pavlu Date: Wed Jul 11 13:17:54 2018 New Revision: 336842 URL: http://llvm.org/viewvc/llvm-project?rev=336842&view=rev Log: Fix setting of empty implicit-section-name attribute Code in `CodeGenModule::SetFunctionAttributes()` could set an empty attribute `implicit-section-name` on a function that is affected by `#pragma clang text="section"`. This is incorrect because the attribute should contain a valid section name. If the function additionally also used `__attribute__((section("section")))` then this could result in emitting the function in a section with an empty name. The patch fixes the issue by removing the problematic code that sets empty `implicit-section-name` from `CodeGenModule::SetFunctionAttributes()` because it is sufficient to set this attribute only from a similar code in `setNonAliasAttributes()` when the function is emitted. Differential Revision: https://reviews.llvm.org/D48916 Added: cfe/trunk/test/CodeGen/clang-sections-attribute.c Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=336842&r1=336841&r2=336842&view=diff == --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Jul 11 13:17:54 2018 @@ -1485,10 +1485,6 @@ void CodeGenModule::SetFunctionAttribute setLinkageForGV(F, FD); setGVProperties(F, FD); - if (FD->getAttr()) { -F->addFnAttr("implicit-section-name"); - } - if (const SectionAttr *SA = FD->getAttr()) F->setSection(SA->getName()); Added: cfe/trunk/test/CodeGen/clang-sections-attribute.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/clang-sections-attribute.c?rev=336842&view=auto == --- cfe/trunk/test/CodeGen/clang-sections-attribute.c (added) +++ cfe/trunk/test/CodeGen/clang-sections-attribute.c Wed Jul 11 13:17:54 2018 @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -emit-llvm -triple arm-none-eabi -o - %s | FileCheck %s + +// Test interaction between __attribute__((section())) and '#pragma clang +// section' directives. The attribute should always have higher priority than +// the pragma. + +// Text tests. +#pragma clang section text=".ext_fun_pragma" +void ext_fun(void) __attribute__((section(".ext_fun_attr"))); +void ext_fun(void) {} +#pragma clang section text="" + +void ext_fun2(void) __attribute__((section(".ext_fun2_attr"))); +#pragma clang section text=".ext_fun2_pragma" +void ext_fun2(void) {} +#pragma clang section text="" + +#pragma clang section text=".int_fun_pragma" +static void int_fun(void) __attribute__((section(".int_fun_attr"), used)); +static void int_fun(void) {} +#pragma clang section text="" + +static void int_fun2(void) __attribute__((section(".int_fun2_attr"), used)); +#pragma clang section text=".int_fun2_pragma" +static void int_fun2(void) {} +#pragma clang section text="" + +// Rodata tests. +#pragma clang section rodata=".ext_const_pragma" +__attribute__((section(".ext_const_attr"))) +const int ext_const = 1; +#pragma clang section rodata="" + +#pragma clang section rodata=".int_const_pragma" +__attribute__((section(".int_const_attr"), used)) +static const int int_const = 1; +#pragma clang section rodata="" + +// Data tests. +#pragma clang section data=".ext_var_pragma" +__attribute__((section(".ext_var_attr"))) +int ext_var = 1; +#pragma clang section data="" + +#pragma clang section data=".int_var_pragma" +__attribute__((section(".int_var_attr"), used)) +static int int_var = 1; +#pragma clang section data="" + +// Bss tests. +#pragma clang section bss=".ext_zvar_pragma" +__attribute__((section(".ext_zvar_attr"))) +int ext_zvar; +#pragma clang section bss="" + +#pragma clang section bss=".int_zvar_pragma" +__attribute__((section(".int_zvar_attr"), used)) +static int int_zvar; +#pragma clang section bss="" + +// CHECK: @ext_const = constant i32 1, section ".ext_const_attr", align 4{{$}} +// CHECK: @int_const = internal constant i32 1, section ".int_const_attr", align 4{{$}} +// CHECK: @ext_var = global i32 1, section ".ext_var_attr", align 4{{$}} +// CHECK: @int_var = internal global i32 1, section ".int_var_attr", align 4{{$}} +// CHECK: @ext_zvar = global i32 0, section ".ext_zvar_attr", align 4{{$}} +// CHECK: @int_zvar = internal global i32 0, section ".int_zvar_attr", align 4{{$}} +// CHECK: define void @ext_fun() #0 section ".ext_fun_attr" +// CHECK: define void @ext_fun2() #0 section ".ext_fun2_attr" +// CHECK: define internal void @int_fun() #0 section ".int_fun_attr" +// CHECK: define internal void @int_fun2() #0 section ".int_fun2_attr" +// +// Function attributes should not include implicit-section-name. +// CHECK-NOT: attributes #0 = {{.*}}implicit-section-name +// +// No other attribute group should be present in the file. +// CHECK-NOT:
[PATCH] D13289: [libc++] Provide additional templates for valarray transcendentals that satisfy the standard synopsis
petpav01 created this revision. petpav01 added a subscriber: cfe-commits. Libc++ provides valarray transcendentals with replacement types. These functions are implemented either as `template` or `template`, where `_Expr` can be `__val_expr` or `valarray`. The patch provides additional function templates for valarray transcendentals that as a parameter use `_Tp` which is a type of elements in the valarray. This is required by the standard and is needed if the user tries to explicitly instantiate the transcendental functions using `_Tp`, for example, `std::abs(int_valarray)`. New templates do not take an additional `_Expr` parameter and so the functions accept only `valarray` as their parameter. This means that if the user explicitly instantiates these function templates and passes `__val_expr` to them, it first needs to be converted to `valarray` and the benefit of the expression template optimization is not present. No performance is lost in the currently possible case where template parameters are deduced because using `__val_expr` as an argument will lead to instantiation of the already present templates. http://reviews.llvm.org/D13289 Files: include/valarray test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/abs_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/acos_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/asin_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_value.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_value_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cos_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cosh_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/exp_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log10_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_value.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_value_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sin_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sinh_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sqrt_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp === --- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp +++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp @@ -33,19 +33,26 @@ int main() { +typedef double T; +T a1[] = {-.9, -.5, 0., .5, .75}; +T a3[] = {-7.1629787019902447e-01, + -4.6211715726000974e-01, + 0.e+00, + 4.6211715726000974e-01, + 6.3514895238728730e-01}; +const unsigned N = sizeof(a1)/sizeof(a1[0]); { -typedef double T; -T a1[] = {-.9, -.5, 0., .5, .75}; -T a3[] = {-7.1629787019902447e-01, - -4.6211715726000974e-01, - 0.e+00, - 4.6211715726000974e-01, - 6.3514895238728730e-01}; -const unsigned N = sizeof(a1)/sizeof(a1[0]); std::valarray v1(a1, N); std::valarray v3 = tanh(v1); assert(v3.size() == v1.size()); for (int i = 0; i < v3.size(); ++i) assert(is_about(v3[i], a3[i], 10)); } +{ +std::valarray v1(a1, N); +std::valarray v3 = std::tanh(v1); +assert(v3.size() == v1.size()); +for (int i = 0; i < v3.size(); ++i) +assert(is_about(v3[i], a3[i], 10)); +} } Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp === --- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp +++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp @@ -33,19 +33,26 @@ int main() { +typedef double T; +T a1[] = {-.9,
Re: [PATCH] D13289: [libc++] Provide additional templates for valarray transcendentals that satisfy the standard synopsis
petpav01 added a comment. It would be probably better if the patch changed the original templates to take only `__val_expr` as there is now no need for them to match valarray too. This should be a simple change but requires additional tests so I will wait for initial feedback that this approach is preferred. http://reviews.llvm.org/D13289 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13289: [libc++] Provide additional templates for valarray transcendentals that satisfy the standard synopsis
petpav01 added a comment. Thank you for having a look at this patch. I should get to updating it as requested soon. Apologies for the delay. http://reviews.llvm.org/D13289 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13289: [libc++] Provide additional templates for valarray transcendentals that satisfy the standard synopsis
petpav01 added a comment. Ping. I would still like to address this problem. Could I please get a review on the last version of the patch? Thanks, Petr http://reviews.llvm.org/D13289 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13289: [libc++] Provide additional templates for valarray transcendentals that satisfy the standard synopsis
petpav01 updated this revision to Diff 40486. petpav01 added a comment. I am not sure if I understand the comment about [17.6.5.4] correctly. It is not clear to me how this part of the standard prevents the user from specifying explicit template parameters for standard functions. It seems odd that the standard would disallow, for example, to use `std::max(1, 2.0)`. New patch changes the transcendentals that accepted any `Expr` (i.e. `valarray` or `__val_expr`) to only accept `__val_expr`. In two cases (`atan2()` and `pow()`) the original template had to be split into four functions: - `func(const __val_expr&, const __val_expr&)` - `func(const __val_expr&, const valarray&)` - `func(const valarray&, const __val_expr&)` - `func(const valarray&, const valarray&)` `is_same` checks on `value_type` of both operands are also added in these cases. Missing thing is a better test coverage. The tests currently do not instantiate the `__val_expr` templates. I am working on this. Could you please send me an example that shows the problem with the ranking in overload resolution so I can add a test for it too? http://reviews.llvm.org/D13289 Files: include/valarray test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/abs_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/acos_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/asin_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_value.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_value_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cos_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cosh_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/exp_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log10_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_value.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_value_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sin_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sinh_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sqrt_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp === --- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp +++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp @@ -33,19 +33,26 @@ int main() { +typedef double T; +T a1[] = {-.9, -.5, 0., .5, .75}; +T a3[] = {-7.1629787019902447e-01, + -4.6211715726000974e-01, + 0.e+00, + 4.6211715726000974e-01, + 6.3514895238728730e-01}; +const unsigned N = sizeof(a1)/sizeof(a1[0]); { -typedef double T; -T a1[] = {-.9, -.5, 0., .5, .75}; -T a3[] = {-7.1629787019902447e-01, - -4.6211715726000974e-01, - 0.e+00, - 4.6211715726000974e-01, - 6.3514895238728730e-01}; -const unsigned N = sizeof(a1)/sizeof(a1[0]); std::valarray v1(a1, N); std::valarray v3 = tanh(v1); assert(v3.size() == v1.size()); for (int i = 0; i < v3.size(); ++i) assert(is_about(v3[i], a3[i], 10)); } +{ +std::valarray v1(a1, N); +std::valarray v3 = std::tanh(v1); +assert(v3.size() == v1.size()); +for (int i = 0; i < v3.size(); ++i) +assert(is_about(v3[i], a3[i], 10)); +} } Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp === --- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp +++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp @@ -33,19 +33,26 @@ int main() { +typedef double T; +T a1[] = {-.9, -.5, 0., .5, .
Re: [PATCH] D13289: [libc++] Provide additional templates for valarray transcendentals that satisfy the standard synopsis
petpav01 updated this revision to Diff 42506. petpav01 added a comment. Updated patch adds more tests and fixes a problem introduced in the previous revision where templates taking `__val_expr` were not correctly protected by SFINAE from immediate context (it introduced same problem with explicit template parameters that I am trying to solve). @Eric: Could you please send me an example that shows the problem with the ranking in overload resolution so I can add a test for it too? I would like to understand this case because if it is not needed then a number of `atan2()` and `pow()` templates can be reduced (to the same amount as in the original patch). http://reviews.llvm.org/D13289 Files: include/valarray test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/abs_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/acos_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/asin_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_valarray_value.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan2_value_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/atan_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cos_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/cosh_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/exp_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log10_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/log_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_valarray_value.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/pow_value_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sin_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sinh_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/sqrt_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp === --- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp +++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tanh_valarray.pass.cpp @@ -33,19 +33,36 @@ int main() { +typedef double T; +T a1[] = {-.9, -.5, 0., .5, .75}; +T a3[] = {-7.1629787019902447e-01, + -4.6211715726000974e-01, + 0.e+00, + 4.6211715726000974e-01, + 6.3514895238728730e-01}; +const unsigned N = sizeof(a1)/sizeof(a1[0]); { -typedef double T; -T a1[] = {-.9, -.5, 0., .5, .75}; -T a3[] = {-7.1629787019902447e-01, - -4.6211715726000974e-01, - 0.e+00, - 4.6211715726000974e-01, - 6.3514895238728730e-01}; -const unsigned N = sizeof(a1)/sizeof(a1[0]); +// tanh(valarray&) std::valarray v1(a1, N); std::valarray v3 = tanh(v1); assert(v3.size() == v1.size()); for (int i = 0; i < v3.size(); ++i) assert(is_about(v3[i], a3[i], 10)); } +{ +// tanh(__val_expr&) +std::valarray v1(a1, N); +std::valarray v3 = tanh(v1 + 0.0); +assert(v3.size() == v1.size()); +for (int i = 0; i < v3.size(); ++i) +assert(is_about(v3[i], a3[i], 10)); +} +{ +// tanh() +std::valarray v1(a1, N); +std::valarray v3 = std::tanh(v1); +assert(v3.size() == v1.size()); +for (int i = 0; i < v3.size(); ++i) +assert(is_about(v3[i], a3[i], 10)); +} } Index: test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp === --- test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp +++ test/std/numerics/numarray/valarray.nonmembers/valarray.transcend/tan_valarray.pass.cpp @@ -33,19 +33,36 @@ int main() { +typedef double T; +T a1[] = {-.9, -.5, 0., .5, .75}; +T a3[] = {-1.2601582175503390e+00, + -5.4630248984379048e-01, + 0.e+00, + 5.4630248984