r343761 - [constexpr] Fix ICE when memcpy() is given a pointer to an incomplete array

2018-10-04 Thread Petr Pavlu via cfe-commits
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

2018-04-21 Thread Petr Pavlu via cfe-commits
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

2018-07-11 Thread Petr Pavlu via cfe-commits
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

2015-09-30 Thread Petr Pavlu via cfe-commits
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

2015-10-03 Thread Petr Pavlu via cfe-commits
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

2015-10-25 Thread Petr Pavlu via cfe-commits
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

2016-01-15 Thread Petr Pavlu via cfe-commits
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

2015-11-18 Thread Petr Pavlu via cfe-commits
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

2015-12-11 Thread Petr Pavlu via cfe-commits
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