[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-22 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
gchatelet added a reviewer: hokein.
Herald added subscribers: cfe-commits, kbarton, xazax.hun, nemanjai.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -9,12 +9,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +24,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -52,6 +52,43 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f = 0;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f = 0;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no
+  // reason to use a double literal here.
+  // TODO(courbet): Provide an automatic fix.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
 void ok(double d) {
   int i = 0;
   i = 1;
@@ -89,15 +126,19 @@
 
 void template_context() {
   f(1, 2);
+  f(1, .5f);
   f(1, .5);
+  f(1, .5l);
 }
 
 #define DERP(i, j) (i += j)
 
 void macro_context() {
   int i = 0;
   DERP(i, 2);
+  DERP(i, .5f);
   DERP(i, .5);
+  DERP(i, .5l);
 }
 
-}  // namespace floats
+} // namespace floats
Index: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
===
--- clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
+++ clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
@@ -27,42 +27,59 @@
   const auto IsFloatExpr =
   expr(hasType(realFloatingPointType()), unless(IsCeilFloorCall));
 
-  // casts:
+  // Casts:
   //   i = 0.5;
   //   void f(int); f(0.5);
-  Finder->addMatcher(implicitCastExpr(hasImplicitDestinationType(isInteger()),
-  hasSourceExpression(IsFloatExpr),
-  unless(hasParent(castExpr())),
-  unless(isInTemplateInstantiation()))
- .b

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-23 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 170605.
gchatelet marked 2 inline comments as done.
gchatelet added a comment.

- Addressing comments


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -9,12 +9,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +24,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -52,6 +52,43 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f = 0;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f = 0;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no
+  // reason to use a double literal here.
+  // TODO(courbet): Provide an automatic fix.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
 void ok(double d) {
   int i = 0;
   i = 1;
@@ -89,15 +126,19 @@
 
 void template_context() {
   f(1, 2);
+  f(1, .5f);
   f(1, .5);
+  f(1, .5l);
 }
 
 #define DERP(i, j) (i += j)
 
 void macro_context() {
   int i = 0;
   DERP(i, 2);
+  DERP(i, .5f);
   DERP(i, .5);
+  DERP(i, .5l);
 }
 
-}  // namespace floats
+} // namespace floats
Index: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
===
--- clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
+++ clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
@@ -27,42 +27,61 @@
   const auto IsFloatExpr =
   expr(hasType(realFloatingPointType()), unless(IsCeilFloorCall));
 
-  // casts:
+  // Casts:
   //   i = 0.5;
   //   void f(int); f(0.5);
-  Finder->addMatcher(implicitCastExpr(hasImplicitDestinationType(isInteger()),
-  hasSourceExpression(IsFloatExpr),
-  unless(hasParent(castExpr())),
-  unless(isInTemplateInstantiation()))
-  

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-24 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added inline comments.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:58
+   const QualType Rhs) {
+  assert(Lhs->isRealType()); // Either integer or floating point.
+  assert(Rhs->isFloatingType()); // Floating point only.

JonasToth wrote:
> Couldn't be the conversion from an `int` to an `enum` be considered narrowing 
> as well? (Not sure about the word of the standard) I think it makes sense to 
> change the `assert` to `return false`
This is a good point but I'd like to implement this as a second patch if you 
don't mind.
I created this bug to track it:
https://bugs.llvm.org/show_bug.cgi?id=39401



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:83
+  } else {
+llvm_unreachable("Invalid state");
   }

hokein wrote:
> We expect that there are only two possible cases here, how about rearrange 
> the code like below, which I think it would simpler and improve code 
> readability.
> 
> ```
> if (const auto *Op = Nodes.getNodeAs("op")) {
>   // handle case for "op".
>   return;
> }
> const auto *Cast = Nodes.getNodeAs("cast");
> assert(Cast && "must be cast cases");
> // ...
> ```
I see.
However I plan to add two improvement to this clang tidy so the number of cases 
will increase.
What do you think about the following code?
```
  if (const auto *Op = Nodes.getNodeAs("op"))
return checkBinaryOperator(*Op);
  if (const auto *Cast = Nodes.getNodeAs("cast"))
return checkCastOperator(*Cast);
  llvm_unreachable("must be binary operator or cast expression");

```


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-24 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 170846.
gchatelet added a comment.

- Update documentation, makes returning code path more explicit.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -9,12 +9,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +24,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -52,6 +52,43 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f = 0;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f = 0;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no
+  // reason to use a double literal here.
+  // TODO(courbet): Provide an automatic fix.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
 void ok(double d) {
   int i = 0;
   i = 1;
@@ -89,15 +126,19 @@
 
 void template_context() {
   f(1, 2);
+  f(1, .5f);
   f(1, .5);
+  f(1, .5l);
 }
 
 #define DERP(i, j) (i += j)
 
 void macro_context() {
   int i = 0;
   DERP(i, 2);
+  DERP(i, .5f);
   DERP(i, .5);
+  DERP(i, .5l);
 }
 
-}  // namespace floats
+} // namespace floats
Index: docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
===
--- docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
+++ docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
@@ -10,13 +10,15 @@
 This rule is part of the "Expressions and statements" profile of the C++ Core
 Guidelines, corresponding to rule ES.46. See
 
-https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-narrowing.
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es46-avoid-lossy-narrowing-truncating-arithmeti

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-24 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added inline comments.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:58
+   const QualType Rhs) {
+  assert(Lhs->isRealType()); // Either integer or floating point.
+  assert(Rhs->isFloatingType()); // Floating point only.

JonasToth wrote:
> gchatelet wrote:
> > JonasToth wrote:
> > > Couldn't be the conversion from an `int` to an `enum` be considered 
> > > narrowing as well? (Not sure about the word of the standard) I think it 
> > > makes sense to change the `assert` to `return false`
> > This is a good point but I'd like to implement this as a second patch if 
> > you don't mind.
> > I created this bug to track it:
> > https://bugs.llvm.org/show_bug.cgi?id=39401
> Implementing this in a follow-up is no problem, but could such a case trigger 
> the assertion by any means?
Not right now because the matchers do not pick integers for the RHS so it never 
matches int to enum conversions.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-24 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 170851.
gchatelet added a comment.

- Add documentation to ReleaseNotes


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -9,12 +9,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +24,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -52,6 +52,43 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f = 0;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f = 0;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no
+  // reason to use a double literal here.
+  // TODO(courbet): Provide an automatic fix.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
 void ok(double d) {
   int i = 0;
   i = 1;
@@ -89,15 +126,19 @@
 
 void template_context() {
   f(1, 2);
+  f(1, .5f);
   f(1, .5);
+  f(1, .5l);
 }
 
 #define DERP(i, j) (i += j)
 
 void macro_context() {
   int i = 0;
   DERP(i, 2);
+  DERP(i, .5f);
   DERP(i, .5);
+  DERP(i, .5l);
 }
 
-}  // namespace floats
+} // namespace floats
Index: docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
===
--- docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
+++ docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
@@ -10,13 +10,15 @@
 This rule is part of the "Expressions and statements" profile of the C++ Core
 Guidelines, corresponding to rule ES.46. See
 
-https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-narrowing.
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es46-avoid-lossy-narrowing-truncating-arithmetic-con

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-24 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In https://reviews.llvm.org/D53488#1273986, @JonasToth wrote:

> Please add a short notice in the release notes for this change.


Sorry I keep on missing to update doc/release notes.
Do you see anything else to add to the Patch?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-24 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 170878.
gchatelet marked an inline comment as done.
gchatelet added a comment.

- Join the two parts of the ReleaseNotes update


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -9,12 +9,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +24,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -52,6 +52,43 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f = 0;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f = 0;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no
+  // reason to use a double literal here.
+  // TODO(courbet): Provide an automatic fix.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
 void ok(double d) {
   int i = 0;
   i = 1;
@@ -89,15 +126,19 @@
 
 void template_context() {
   f(1, 2);
+  f(1, .5f);
   f(1, .5);
+  f(1, .5l);
 }
 
 #define DERP(i, j) (i += j)
 
 void macro_context() {
   int i = 0;
   DERP(i, 2);
+  DERP(i, .5f);
   DERP(i, .5);
+  DERP(i, .5l);
 }
 
-}  // namespace floats
+} // namespace floats
Index: docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
===
--- docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
+++ docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
@@ -10,13 +10,15 @@
 This rule is part of the "Expressions and statements" profile of the C++ Core
 Guidelines, corresponding to rule ES.46. See
 
-https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-narrowing.
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-25 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked 2 inline comments as done.
gchatelet added a comment.

In https://reviews.llvm.org/D53488#1274205, @JonasToth wrote:

> Did you run this code over a real-world code-base and did you find new stuff 
> and/or false positives or the like?


Yes I did run it over our code base. I didn't find false positive but 98% of 
the warnings are from large generated lookup table initializers, e.g. `const 
static float kTable[] = {0.0, 2.0, ... };`
Since every number in the list triggers the warning, it accounts for most of 
them.

I scrutinized a few hundreds of the rest: none were actual bugs (although it's 
hard to tell sometimes), most are legit like `float value = 0.0;` but I also 
found some oddities 

 from generated headers.

To me the warnings are useful and if it were my code I'd be willing to fix 
them. That said, I'd totally understand that many people would find them 
useless or annoying.
What do you think? Shall we still commit this as is?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-25 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In https://reviews.llvm.org/D53488#1275786, @hokein wrote:

> In https://reviews.llvm.org/D53488#1275750, @gchatelet wrote:
>
> > In https://reviews.llvm.org/D53488#1274205, @JonasToth wrote:
> >
> > > Did you run this code over a real-world code-base and did you find new 
> > > stuff and/or false positives or the like?
> >
> >
> > Yes I did run it over our code base. I didn't find false positive but 98% 
> > of the warnings are from large generated lookup table initializers, e.g. 
> > `const static float kTable[] = {0.0, 2.0, ... };`
> >  Since every number in the list triggers the warning, it accounts for most 
> > of them.
> >
> > I scrutinized a few hundreds of the rest: none were actual bugs (although 
> > it's hard to tell sometimes), most are legit like `float value = 0.0;` but 
> > I also found some oddities 
> > 
> >  from generated headers.
> >
> > To me the warnings are useful and if it were my code I'd be willing to fix 
> > them. That said, I'd totally understand that many people would find them 
> > useless or annoying.
> >  What do you think? Shall we still commit this as is?
>
>
> It would be nice to know how many new findings does this patch introduce 
> (number of findings before the patch vs after). If it is not too much, it is 
> fine the commit as it is.
>  I'd suggest to run the check on llvm code repository (using 
> `clang-tidy/tool/run-clang-tidy.py`, and only enable 
> `cppcoreguidelines-narrowing-conversions`).


I'll get back with some numbers.

In the meantime I found this one which is interesting
https://github.com/intel/ipmctl/blob/master/src/os/efi_shim/lnx_efi_api.c#L45
`spec.tv_nsec` (which is signed long) is converted to double and back to int64. 
There surely can be some loss in the process since `double` can //only// 
express 2^52 integers (2^52ns is about 52 days)


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 171692.
gchatelet added a comment.

- Add more checks, disable bool implicit casts warning, enable ternary operator 
warnings.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -- --
+// -target x86_64-unknown-linux
 
 float ceil(float);
 namespace std {
@@ -9,12 +10,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +25,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -52,6 +53,129 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no reason to use a double literal here.
+  // TODO(courbet): Provide an automatic fix.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_integer_to_floating() {
+  {
+long long ll; // 64 bits
+float f = ll; // doesn't fit in 24 bits
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [cppcoreguidelines-narrowing-conversions]
+double d = ll; // doesn't fit in 53 bits.
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [cppcoreguidelines-narrowing-conversions]
+  }
+  {
+int i;   // 32 bits
+float f = i; // doesn't fit in 24 bits
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
+double d = i; // fits in 53 bits.
+  }
+

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

So I've updated the code to add more narrowing conversions.
It now tests constant expressions against receiving type, do not warn about 
implicit bool casting, handles ternary operator with constant expressions.

I ran it on our code base: results look legit.
I'll ping back here with numbers for llvm once I figured out how to build the 
database the tool is complaining about :)


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

So I ran `llvm/tools/clang/tools/extra/clang-tidy/tool/run-clang-tidy.py`
The bare version produces `65664` unique findings.
The version restricted to `cppcoreguidelines-narrowing-conversions` produces 
`4323` unique findings. That's about `+7%` of findings.
I can post some random ones is you're interested.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 171717.
gchatelet marked 4 inline comments as done.
gchatelet added a comment.

- Remove leftover


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -- --
+// -target x86_64-unknown-linux
 
 float ceil(float);
 namespace std {
@@ -9,12 +10,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +25,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -52,6 +53,129 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no reason to use a double literal here.
+  // TODO(courbet): Provide an automatic fix.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_integer_to_floating() {
+  {
+long long ll; // 64 bits
+float f = ll; // doesn't fit in 24 bits
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [cppcoreguidelines-narrowing-conversions]
+double d = ll; // doesn't fit in 53 bits.
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [cppcoreguidelines-narrowing-conversions]
+  }
+  {
+int i;   // 32 bits
+float f = i; // doesn't fit in 24 bits
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
+double d = i; // fits in 53 bits.
+  }
+  {
+short s;  // 16 

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

Here are 15 random ones from **llvm** synced at 
`8f9fb8bab2e9b5b27fe40d700d2abe967b99fbb5`.

  lib/Target/ARM/AsmParser/ARMAsmParser.cpp:3802:31: warning: narrowing 
conversion from 'int' to 'unsigned int' 
[cppcoreguidelines-narrowing-conversions]
  tools/dsymutil/MachOUtils.cpp:330:10: warning: narrowing conversion from 
'unsigned long' to 'unsigned int' [cppcoreguidelines-narrowing-conversions]
  lib/Target/X86/X86ISelDAGToDAG.cpp:1237:14: warning: narrowing conversion 
from 'int' to 'unsigned int' [cppcoreguidelines-narrowing-conversions]
  tools/llvm-objdump/MachODump.cpp:7998:12: warning: narrowing conversion from 
'int' to 'unsigned int' [cppcoreguidelines-narrowing-conversions]
  lib/CodeGen/MachinePipeliner.cpp:3268:11: warning: narrowing conversion from 
'int' to 'unsigned int' [cppcoreguidelines-narrowing-conversions]
  lib/CodeGen/MIRParser/MIRParser.cpp:823:41: warning: narrowing conversion 
from 'int' to 'unsigned int' [cppcoreguidelines-narrowing-conversions]
  lib/Analysis/MemoryBuiltins.cpp:610:59: warning: narrowing conversion from 
'int' to 'unsigned int' [cppcoreguidelines-narrowing-conversions]
  lib/Analysis/ValueTracking.cpp:2291:21: warning: narrowing conversion from 
'unsigned long' to 'unsigned int' [cppcoreguidelines-narrowing-conversions]
  lib/Target/ARM/ARMLoadStoreOptimizer.cpp:1470:43: warning: narrowing 
conversion from 'int' to 'unsigned int' 
[cppcoreguidelines-narrowing-conversions]
  lib/Target/AArch64/AArch64ISelDAGToDAG.cpp:2300:14: warning: narrowing 
conversion from 'int' to 'unsigned int' 
[cppcoreguidelines-narrowing-conversions]
  lib/Target/X86/X86TargetTransformInfo.cpp:2590:27: warning: narrowing 
conversion from 'int' to 'unsigned int' 
[cppcoreguidelines-narrowing-conversions]
  lib/Target/ARM/ARMFrameLowering.cpp:1770:27: warning: narrowing conversion 
from 'int' to 'unsigned int' [cppcoreguidelines-narrowing-conversions]
  lib/Target/ARM/ARMConstantIslandPass.cpp:514:22: warning: narrowing 
conversion from 'int' to 'unsigned int' 
[cppcoreguidelines-narrowing-conversions]
  lib/Transforms/Vectorize/LoopVectorize.cpp:5500:13: warning: narrowing 
conversion from 'int' to 'unsigned int' 
[cppcoreguidelines-narrowing-conversions]
  lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp:1199:54: warning: narrowing 
conversion from 'int' to 'unsigned int' 
[cppcoreguidelines-narrowing-conversions]




Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:14
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"

Szelethus wrote:
> Is  `APInt` used anywhere?
Good catch thx.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:32
 
-  const auto IsFloatExpr =
-  expr(hasType(realFloatingPointType()), unless(IsCeilFloorCall));
+  const auto IsBuiltinOrEnumType = anyOf(builtinType(), enumType());
 

JonasToth wrote:
> This matcher seems no to be used, did I overlook sth?
It's a leftover indeed thx for noticing.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 171826.
gchatelet marked 12 inline comments as done.
gchatelet added a comment.

- Address comments


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -- --
+// -target x86_64-unknown-linux
 
 float ceil(float);
 namespace std {
@@ -9,12 +10,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +25,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -52,6 +53,137 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no reason to use a double literal here.
+  // TODO(courbet): Provide an automatic fix.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_integer_to_floating() {
+  {
+long long ll; // 64 bits
+float f = ll; // doesn't fit in 24 bits
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [cppcoreguidelines-narrowing-conversions]
+double d = ll; // doesn't fit in 53 bits.
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [cppcoreguidelines-narrowing-conversions]
+  }
+  {
+int i;   // 32 bits
+float f = i; // doesn't fit in 24 bits
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
+double d = i; // fits in 53 bits.
+  }
+  {
+short n1, n2;
+   

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-10-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked an inline comment as done.
gchatelet added inline comments.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:42
+   unless(hasParent(castExpr())),
+   unless(isInTemplateInstantiation()))
+  .bind("cast"),

JonasToth wrote:
> Here and in the matcher below:
> 
> `isInTemplateInstantiation` is a wide range, if you match only on 
> `isTypeDependent()` it would remove the false negatives from templates but 
> still catch clear cases that are within a template function.
> 
> With the current implementation non-type-templates would be ignored as well.
> IMHO that could be done in a follow-up to keep the scope on one thing.
Sounds good, let's fix this in a follow-up patch.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:92
+
+// 'One' is created with PrecisionBits plus two bytes:
+// - One to express the missing negative value of 2's complement

JonasToth wrote:
> Maybe repleace `One` with `1.0`? It sounds slightly weird with the following 
> `One`s
It's a leftover, I've reworded and changed the code as well.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:149
+  const QualType RhsType = Rhs->getType();
+  if (Lhs->isValueDependent() || Rhs->isValueDependent() ||
+  LhsType->isDependentType() || RhsType->isDependentType())

JonasToth wrote:
> you can shorten this condition with `isDependentType`
I tried using the following but it crashes when I run clang tidy other our 
codebase:
```
if (LhsType->isDependentType() || RhsType->isDependentType())
return false;
```

Maybe I misunderstood what you suggested?



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:165
+  if (const auto *CO = llvm::dyn_cast(Rhs)) {
+const bool NarrowLhs = diagIfNarrowConstant(
+Context, CO->getLHS()->getExprLoc(), Lhs, CO->getLHS());

JonasToth wrote:
> you could remove both temporaries and return directly and then ellide the 
> braces.
> If you don't like that please remove the `const`
I have to keep both variables or the first one might shortcircuit the second 
that goes undetected.
e.g. `unsigned char c = b ? 1 : -1;`


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-11-05 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked 8 inline comments as done.
gchatelet added inline comments.



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:164
+  while (i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 
'int' to 'bool' [cppcoreguidelines-narrowing-conversions]
+  }

JonasToth wrote:
> lebedev.ri wrote:
> > courbet wrote:
> > > What about providing a fix for this one :
> > > `while (i != 0) {`
> > Is this //actually// a narrowing conversion as per the CPPCG?
> > Conversion to bool is a special case, it's not a truncation, but a `x != 0`.
> > I'd think cases like these where bool was pretty clearly meant (`if()`, 
> > `while()`, `for()`, ???) should be exempt.
> No it is not an narrowing conversion the CPPCG are concerned: 
> https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es46-avoid-lossy-narrowing-truncating-arithmetic-conversions
> 
> Short: 
> ```
> ES.46: Avoid lossy (narrowing, truncating) arithmetic conversions
> 
> Enforcement
> 
> A good analyzer can detect all narrowing conversions. However, flagging all 
> narrowing conversions will lead to a lot of false positives. Suggestions:
> 
> - flag all floating-point to integer conversions (maybe only float->char 
> and double->int. Here be dragons! we need data)
> - flag all long->char (I suspect int->char is very common. Here be 
> dragons! we need data)
> - consider narrowing conversions for function arguments especially suspect
> ```
> 
> We do have a readability-check that is concerned about int -> bool 
> conversions. Because of that I think we could safely ignore the `int->bool` 
> conversion. 
> But `float -> bool` is still suspicious in my opinion. It has the same 
> semantics, but comparing `float` on equality is dangerous and one could argue 
> it shall be enforced through point 1 (all float-to-int conversions).
@JonasToth Do you have the name of the readability check so I can document the 
behavior?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-11-06 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 172778.
gchatelet marked 7 inline comments as done.
gchatelet added a comment.

- Addressing comments and enhancing diagnostics


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -- --
+// -target x86_64-unknown-linux
 
 float ceil(float);
 namespace std {
@@ -9,12 +10,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +25,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -38,7 +39,7 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   // We warn on the following even though it's not dangerous because there is no
   // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
   i += 2.0;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;
@@ -52,6 +53,234 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no reason to use a double literal here.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_integer_to_floating() {
+  {
+long long ll; // 64 bits

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-11-07 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added inline comments.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:178
+  return;
+// Conversions to unsigned integer are well defined and follow modulo 2
+// arithmetic.

JonasToth wrote:
> I am surprised by `following modulo 2 arithmetic` and think it's a bit 
> misleading. Writing just `module arithmetic` is probably better, as `module 
> 2` somewhat implies there a only 2 valid values (0, 1).
> 
> Is this the `int` -> `unsigned int` case path? That seems worth diagnosing 
> too.
Yes, thx for noticing. I updated the comment, I think it's better now.

Indeed this is the `int` -> `unsigned int` case path. Warning here would lead 
to a lot of noise for everybody doing bitwise operations since `-1` is a 
compact way to represent the maximum value. Since the semantic is valid and 
well defined by the standard I'm unsure it's worth the pain. I'm open to 
suggestions though.

Maybe a good way to figure out is what would be the correct fix for say 
`unsigned long AllBits = -1;`


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-11-07 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 172904.
gchatelet marked 2 inline comments as done.
gchatelet added a comment.

- Addressing comments


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -- --
+// -target x86_64-unknown-linux
 
 float ceil(float);
 namespace std {
@@ -9,12 +10,12 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -24,11 +25,11 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
@@ -38,7 +39,7 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   // We warn on the following even though it's not dangerous because there is no
   // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
   i += 2.0;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;
@@ -52,6 +53,234 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f;
+  f += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  // We warn on the following even though it's not dangerous because there is no reason to use a double literal here.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+
+  f *= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f /= 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_integer_to_floating() {
+  {
+long long ll; // 64 bits
+float f = ll; // doe

[PATCH] D53488: [clang-tidy] Catching narrowing from double to float.

2018-11-08 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

Is this good enough to go? @JonasToth


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-09 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 173343.
gchatelet marked 13 inline comments as done.
gchatelet added a comment.

- Addressing comments, adding Option to disable FP to FP narrowing warnings, 
handling FP literals.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -config="{CheckOptions: [{key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 1}]}" -- -target x86_64-unknown-linux
 
 float ceil(float);
 namespace std {
@@ -9,47 +9,287 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += d;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   // We warn on the following even though it's not dangerous because there is no
   // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
   i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+}
+
+do

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-12 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 173633.
gchatelet marked 2 inline comments as done.
gchatelet added a comment.

- Address comments + fix hex values display


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -config="{CheckOptions: [{key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 1}]}" -- -target x86_64-unknown-linux
 
 float ceil(float);
 namespace std {
@@ -9,47 +9,290 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += d;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   // We warn on the following even though it's not dangerous because there is no
   // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
   i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+}
+
+double operator"" _double(unsigned long long);
+
+float nar

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-12 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added inline comments.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:178
+  return;
+// Conversions to unsigned integer are well defined and follow modulo 2
+// arithmetic.

JonasToth wrote:
> gchatelet wrote:
> > JonasToth wrote:
> > > I am surprised by `following modulo 2 arithmetic` and think it's a bit 
> > > misleading. Writing just `module arithmetic` is probably better, as 
> > > `module 2` somewhat implies there a only 2 valid values (0, 1).
> > > 
> > > Is this the `int` -> `unsigned int` case path? That seems worth 
> > > diagnosing too.
> > Yes, thx for noticing. I updated the comment, I think it's better now.
> > 
> > Indeed this is the `int` -> `unsigned int` case path. Warning here would 
> > lead to a lot of noise for everybody doing bitwise operations since `-1` is 
> > a compact way to represent the maximum value. Since the semantic is valid 
> > and well defined by the standard I'm unsure it's worth the pain. I'm open 
> > to suggestions though.
> > 
> > Maybe a good way to figure out is what would be the correct fix for say 
> > `unsigned long AllBits = -1;`
> Comment is fine :)
> 
> I though that we have check that diagnoses `unsigned i = -1;` but I don't 
> find it right now (maybe its still in review or so, i belive it was related 
> to introducing `std::numeric_limits<>`).
> As its well defined and not narrowing and not mentionend by the CPPCG in that 
> section its ok, maybe worth an option in the future?
An Option to warn on these sound like a good idea.
I added TODOs.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-13 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 173836.
gchatelet marked 6 inline comments as done.
gchatelet added a comment.

- Address comments


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -config="{CheckOptions: [{key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 1}]}" -- -target x86_64-unknown-linux
 
 float ceil(float);
 namespace std {
@@ -9,47 +9,290 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += d;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   // We warn on the following even though it's not dangerous because there is no
   // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
   i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+}
+
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_retur

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-13 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added inline comments.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:299
+  Rhs->isCXX11ConstantExpr(Context, &Constant)) {
+if (Constant.isFloat())
+  diagIfNarrowFloatingPointConstant(Context, SourceLoc, Lhs, Rhs, 
Constant);

JonasToth wrote:
> Why is the return here `true` even without diagnostic?
Good catch


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-13 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 173844.
gchatelet added a comment.

- Remove debugging leftover


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -config="{CheckOptions: [{key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 1}]}" -- -target x86_64-unknown-linux
 
 float ceil(float);
 namespace std {
@@ -9,47 +9,290 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += d;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   // We warn on the following even though it's not dangerous because there is no
   // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
   i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+}
+
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+  // CHECK-ME

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-13 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In https://reviews.llvm.org/D53488#1296940, @JonasToth wrote:

> So, finally LGTM :)
>  Please give @aaron.ballman a chance to comment, as he reviewed too.
>
> Thanks for your patch!


Thank you for bearing with me.
Waiting for input from @aaron.ballman


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-14 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

Thx for the review. I have two suggestions in the comments let me know what you 
think.




Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:79-81
+  // TODO: Provide an automatic fix if the number is exactly representable in 
the destination type.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 
constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions]

aaron.ballman wrote:
> This is not a narrowing conversion -- there should be no diagnostic here. See 
> [dcl.init.list]p7.
Thx for pointing this out.
I would like to keep the diagnostic (without mentioning the narrowing) because 
there is no reason to write `2.0` instead of `2.0f`. WDYT?



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:99
+void narrow_integer_to_floating() {
+  {
+long long ll; // 64 bits

aaron.ballman wrote:
> Missing tests involving literals, which are not narrowing conversions. e.g., 
> `float f = 1ULL;` should not diagnose.
This is handled on l.262



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:174
+  c = uc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 
'unsigned char' to 'char' is implementation-defined 
[cppcoreguidelines-narrowing-conversions]
+  c = us;

aaron.ballman wrote:
> This is only true on architectures where `char` is defined to be `signed 
> char` rather than `unsigned char`.
This is taken care of. The test fails when adding `-funsigned-char`.
The current test is executed with `-target x86_64-unknown-linux` which should 
imply `-fsigned-char`. Anyways, I'll add `-fsigned-char` to make sure this is 
obvious.



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:188
+  i = l;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' 
to 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  i = ll;

aaron.ballman wrote:
> This is only narrowing if `sizeof(int) < sizeof(long)` which is not the case 
> on all architectures.
Yes this is taken care of in the code, the size of the type must be smaller.
It works here because the test runs with `-target x86_64-unknown-linux`



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:211
+  ll = ul;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 
'unsigned long' to 'long long' is implementation-defined 
[cppcoreguidelines-narrowing-conversions]
+  ll = ull;

aaron.ballman wrote:
> Wha? How does one narrow from an unsigned 32-bit number to a signed 
> 64-bit number?
`unsigned long` is unsigned 64-bit so it does not fit in signed 64-bit.
https://godbolt.org/z/VnmG0s



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:228
+void narrow_constant_to_signed_integer_is_not_ok() {
+  char c1 = -128;
+  char c2 = 127;

aaron.ballman wrote:
> This may be narrowing on an implementation that defines `char` to be 
> `unsigned`.
Same as previous comments. Would it make sense to create a different test with 
`-funsigned-char` to check these behaviors?



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:232
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from 
constant value -129 (0xFF7F) of type 'int' to 'char' is 
implementation-defined [cppcoreguidelines-narrowing-conversions]
+  char c4 = 128;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from 
constant value 128 (0x0080) of type 'int' to 'char' is 
implementation-defined [cppcoreguidelines-narrowing-conversions]

aaron.ballman wrote:
> This may be fine on implementations that define `char` to be `unsigned`.
ditto


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-14 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 174044.
gchatelet marked 7 inline comments as done.
gchatelet added a comment.

- State char signess clearly


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -config="{CheckOptions: [{key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 1}]}" -- -target x86_64-unknown-linux -fsigned-char
 
 float ceil(float);
 namespace std {
@@ -9,47 +9,290 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += d;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   // We warn on the following even though it's not dangerous because there is no
   // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
   i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+}
+
+double operator"" _double(unsigned long long);
+
+float narr

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-16 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 174374.
gchatelet marked 13 inline comments as done.
gchatelet added a comment.

- Addressed comments


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -config="{CheckOptions: [{key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 1}]}" -- -target x86_64-unknown-linux -fsigned-char
 
 float ceil(float);
 namespace std {
@@ -9,47 +9,298 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_double_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 }
 
-void not_ok_binary_ops(double d) {
+void narrow_double_to_int_not_ok_binary_ops(double d) {
   int i = 0;
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += d;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   // We warn on the following even though it's not dangerous because there is no
   // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
+  // TODO: Provide an automatic fix if the number is exactly representable in the destination type.
   i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
 
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conve

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-16 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added inline comments.



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:79-81
+  // TODO: Provide an automatic fix if the number is exactly representable in 
the destination type.
+  f += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 
constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions]

aaron.ballman wrote:
> gchatelet wrote:
> > aaron.ballman wrote:
> > > This is not a narrowing conversion -- there should be no diagnostic here. 
> > > See [dcl.init.list]p7.
> > Thx for pointing this out.
> > I would like to keep the diagnostic (without mentioning the narrowing) 
> > because there is no reason to write `2.0` instead of `2.0f`. WDYT?
> I see no reason to warn on a literal value that isn't changed as a result of 
> the notional narrowing. The standard clearly defines the behavior, so I think 
> that would be needlessly chatty.
Done. Plus added som tests.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-22 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 175030.
gchatelet marked an inline comment as done.
gchatelet added a comment.

- Refactored the code to make it simpler, added more tests


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-extras.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -- -- -target x86_64-unknown-linux -fsigned-char
 
 float ceil(float);
 namespace std {
@@ -9,47 +9,284 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_fp_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-}
-
-void not_ok_binary_ops(double d) {
-  int i = 0;
+  i += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += d;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  // We warn on the following even though it's not dangerous because there is no
-  // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
-  i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += 2.0f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion f

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-22 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked 2 inline comments as done.
gchatelet added inline comments.



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:42-44
   i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 
'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 
constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;

aaron.ballman wrote:
> I don't think these should diagnose. They're both harmless as the literal 
> values are exactly representable in the destination type.
Yes indeed they are harmless but why not write the correct literal in the first 
place?
I'm keeping these warnings for now. Let me know if you feel strongly about it.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-22 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 175033.
gchatelet marked an inline comment as done.
gchatelet added a comment.

- Reverting the WarnOnFloatingPointNarrowingConversion option to be on by 
default


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-extras.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t -config="{CheckOptions: [{key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 0}]}" -- -target x86_64-unknown-linux -fsigned-char
 
 float ceil(float);
 namespace std {
@@ -9,47 +9,284 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_fp_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-}
-
-void not_ok_binary_ops(double d) {
-  int i = 0;
+  i += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += d;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  // We warn on the following even though it's not dangerous because there is no
-  // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
-  i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from const

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-23 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 175139.
gchatelet added a comment.

- Added a new option warn about wrong type literals


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53488/new/

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  
test/clang-tidy/cppcoreguidelines-narrowing-conversions-castingliterals-option.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
  
test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,9 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -config="{CheckOptions: [ \
+// RUN:   {key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 0}, \
+// RUN:   {key: "cppcoreguidelines-narrowing-conversions.WarnOnCastingLiterals", value: 0} \
+// RUN: ]}" \
+// RUN: -- -target x86_64-unknown-linux -fsigned-char
 
 float ceil(float);
 namespace std {
@@ -9,47 +14,282 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_fp_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-}
-
-void not_ok_binary_ops(double d) {
-  int i = 0;
+  i += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += d;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  // We warn on the following even though it's not dangerous because there is no
-  // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
-  i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-c

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-23 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked an inline comment as done.
gchatelet added inline comments.



Comment at: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp:42-44
   i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 
'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 
constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 2.0f;

aaron.ballman wrote:
> gchatelet wrote:
> > aaron.ballman wrote:
> > > I don't think these should diagnose. They're both harmless as the literal 
> > > values are exactly representable in the destination type.
> > Yes indeed they are harmless but why not write the correct literal in the 
> > first place?
> > I'm keeping these warnings for now. Let me know if you feel strongly about 
> > it.
> > Yes indeed they are harmless but why not write the correct literal in the 
> > first place?
> 
> Why force the user to modify their code when the behavior will be exactly the 
> same as before?
> 
> > I'm keeping these warnings for now. Let me know if you feel strongly about 
> > it.
> 
> I don't feel very strongly on this case, but it seems needlessly chatty to me 
> to diagnose code that's not incorrect. For instance, this code could exist in 
> a (system) header file that the user doesn't have the ability to correct.
I've added a `WarnOnCastingLiterals` option to display them.
It's on by default.
Let me know if you have a better name, I'm not super happy with it.
Let me know if you think it should be off by default.


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53488/new/

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-26 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 175203.
gchatelet marked 16 inline comments as done.
gchatelet added a comment.

- Addressing comments


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53488/new/

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  
test/clang-tidy/cppcoreguidelines-narrowing-conversions-castingliterals-option.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
  
test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,9 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -config="{CheckOptions: [ \
+// RUN:   {key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 0}, \
+// RUN:   {key: "cppcoreguidelines-narrowing-conversions.PedanticMode", value: 0} \
+// RUN: ]}" \
+// RUN: -- -target x86_64-unknown-linux -fsigned-char
 
 float ceil(float);
 namespace std {
@@ -9,47 +14,282 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_fp_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-}
-
-void not_ok_binary_ops(double d) {
-  int i = 0;
+  i += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += d;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  // We warn on the following even though it's not dangerous because there is no
-  // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
-  i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narro

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-26 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

Thank you for bearing with me  @aaron.ballman.




Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:259-263
+void NarrowingConversionsCheck::handleIntegralToBoolean(
+const ASTContext &Context, SourceLocation SourceLoc, const Expr &Lhs,
+const Expr &Rhs) {
+  // Conversion from Integral to Bool value is well defined.
+}

aaron.ballman wrote:
> Why is this function needed at all?
The two empty functions are placeholders so the cases handled by `ImplicitCast` 
and `BinaryOp` are the same.
I'll add some documentation.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:311-315
+void NarrowingConversionsCheck::handleBooleanToSignedIntegral(
+const ASTContext &Context, SourceLocation SourceLoc, const Expr &Lhs,
+const Expr &Rhs) {
+  // Conversion from Bool to SignedIntegral value is well defined.
+}

aaron.ballman wrote:
> Why is this function needed at all?
Ditto.



Comment at: clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp:372
+  if (const auto *CO = llvm::dyn_cast(&Rhs)) {
+// We create variables so we make sure both sides of the
+// ConditionalOperator are evaluated, the || operator would short ciruit

aaron.ballman wrote:
> What variables are created here?
Leftover. I rewrote the comment.


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53488/new/

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-26 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 175204.
gchatelet added a comment.

- Fixing  documentation.


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53488/new/

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  
test/clang-tidy/cppcoreguidelines-narrowing-conversions-castingliterals-option.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
  
test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,9 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -config="{CheckOptions: [ \
+// RUN:   {key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 0}, \
+// RUN:   {key: "cppcoreguidelines-narrowing-conversions.PedanticMode", value: 0} \
+// RUN: ]}" \
+// RUN: -- -target x86_64-unknown-linux -fsigned-char
 
 float ceil(float);
 namespace std {
@@ -9,47 +14,282 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_fp_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-}
-
-void not_ok_binary_ops(double d) {
-  int i = 0;
+  i += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += d;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  // We warn on the following even though it's not dangerous because there is no
-  // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
-  i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-26 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 175231.
gchatelet marked 4 inline comments as done.
gchatelet added a comment.

- Removed redundant options in regression tests


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53488/new/

https://reviews.llvm.org/D53488

Files:
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
  
test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
  
test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
  test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
===
--- test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,8 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -config="{CheckOptions: [ \
+// RUN:   {key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 0}, \
+// RUN: ]}" \
+// RUN: -- -target x86_64-unknown-linux -fsigned-char
 
 float ceil(float);
 namespace std {
@@ -9,47 +13,282 @@
 namespace floats {
 
 struct ConvertsToFloat {
-  operator float() const { return 0.5; }
+  operator float() const { return 0.5f; }
 };
 
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
 
-void not_ok(double d) {
+void narrow_fp_to_int_not_ok(double d) {
   int i = 0;
   i = d;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = static_cast(d);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i = ConvertsToFloat();
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i = 15_Pa;
+  i = 15_float;
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-}
-
-void not_ok_binary_ops(double d) {
-  int i = 0;
+  i += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += d;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  // We warn on the following even though it's not dangerous because there is no
-  // reason to use a double literal here.
-  // TODO(courbet): Provide an automatic fix.
-  i += 2.0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
-  i += 2.0f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
-
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i *= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i /= 0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
   i += (double)0.5f;
-  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning

[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-26 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D53488#1307834 , @aaron.ballman 
wrote:

> LGTM!


Thx ! \O/


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53488/new/

https://reviews.llvm.org/D53488



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53488: [clang-tidy] Improving narrowing conversions

2018-11-26 Thread Guillaume Chatelet via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL347570: [clang-tidy] Improving narrowing conversions 
(authored by gchatelet, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53488/new/

https://reviews.llvm.org/D53488

Files:
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
  clang-tools-extra/trunk/docs/ReleaseNotes.rst
  
clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.rst
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp

Index: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
===
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
@@ -24,10 +24,76 @@
 /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-narrowing-conversions.html
 class NarrowingConversionsCheck : public ClangTidyCheck {
 public:
-  NarrowingConversionsCheck(StringRef Name, ClangTidyContext *Context)
-  : ClangTidyCheck(Name, Context) {}
+  NarrowingConversionsCheck(StringRef Name, ClangTidyContext *Context);
+
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  void diagNarrowType(SourceLocation SourceLoc, const Expr &Lhs,
+  const Expr &Rhs);
+
+  void diagNarrowTypeToSignedInt(SourceLocation SourceLoc, const Expr &Lhs,
+ const Expr &Rhs);
+
+  void diagNarrowIntegerConstant(SourceLocation SourceLoc, const Expr &Lhs,
+ const Expr &Rhs, const llvm::APSInt &Value);
+
+  void diagNarrowIntegerConstantToSignedInt(SourceLocation SourceLoc,
+const Expr &Lhs, const Expr &Rhs,
+const llvm::APSInt &Value,
+const uint64_t HexBits);
+
+  void diagNarrowConstant(SourceLocation SourceLoc, const Expr &Lhs,
+  const Expr &Rhs);
+
+  void diagConstantCast(SourceLocation SourceLoc, const Expr &Lhs,
+const Expr &Rhs);
+
+  void diagNarrowTypeOrConstant(const ASTContext &Context,
+SourceLocation SourceLoc, const Expr &Lhs,
+const Expr &Rhs);
+
+  void handleIntegralCast(const ASTContext &Context, SourceLocation SourceLoc,
+  const Expr &Lhs, const Expr &Rhs);
+
+  void handleIntegralToBoolean(const ASTContext &Context,
+   SourceLocation SourceLoc, const Expr &Lhs,
+   const Expr &Rhs);
+
+  void handleIntegralToFloating(const ASTContext &Context,
+SourceLocation SourceLoc, const Expr &Lhs,
+const Expr &Rhs);
+
+  void handleFloatingToIntegral(const ASTContext &Context,
+SourceLocation SourceLoc, const Expr &Lhs,
+const Expr &Rhs);
+
+  void handleFloatingToBoolean(const ASTContext &Context,
+   SourceLocation SourceLoc, const Expr &Lhs,
+   const Expr &Rhs);
+
+  void handleBooleanToSignedIntegral(const ASTContext &Context,
+ SourceLocation SourceLoc, const Expr &Lhs,
+ const Expr &Rhs);
+
+  void handleFloatingCast(const ASTContext &Context, SourceLocation SourceLoc,
+  const Expr &Lhs, const Expr &Rhs);
+
+  void handleBinaryOperator(const ASTContext &Context, SourceLocation SourceLoc,
+const Expr &Lhs, const Expr &Rhs);
+
+  bool handleConditionalOperator(const ASTContext &Context, const Expr &Lhs,
+ const Expr &Rhs);
+
+  void handleImplicitCast(const ASTContext &Context,
+  const ImplicitCastExpr &Cast);
+
+  void handleBinaryOperator(const ASTContext &Context,
+const BinaryOperator &Op);
+
+  const bool WarnOnFloatingPointNarrowingConversion;
+  const bool PedanticMode;
 };
 
 } // 

[PATCH] D60719: Fixing freestanding for memcpy.

2019-04-15 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
gchatelet added a reviewer: courbet.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya.
Herald added projects: clang, LLVM.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D60719

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5464,6 +5464,14 @@
   }
 }
 
+static bool IsForceInlineLibc(const SelectionDAG &DAG) {
+  const Module *M = DAG.getMachineFunction().getFunction().getParent();
+  if (auto *MD = mdconst::extract_or_null(
+  M->getModuleFlag("force-inline-libc")))
+return MD->getZExtValue();
+  return false;
+}
+
 /// Lower the call to the specified intrinsic function. If we want to emit this
 /// as a call to a named external function, return the name. Otherwise, lower 
it
 /// and return null.
@@ -5537,10 +5545,11 @@
 unsigned Align = MinAlign(DstAlign, SrcAlign);
 bool isVol = MCI.isVolatile();
 bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());
+bool IsAlwaysInline = IsForceInlineLibc(DAG);
 // FIXME: Support passing different dest/src alignments to the memcpy DAG
 // node.
 SDValue MC = DAG.getMemcpy(getRoot(), sdl, Op1, Op2, Op3, Align, isVol,
-   false, isTC,
+   IsAlwaysInline, isTC,
MachinePointerInfo(I.getArgOperand(0)),
MachinePointerInfo(I.getArgOperand(1)));
 updateDAGForMaybeTailCall(MC);
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6090,6 +6090,9 @@
   // beyond the given memory regions. But fixing this isn't easy, and most
   // people don't care.
 
+  assert(MF->getFunction().getParent()->getModuleFlag("force-inline-libc") ==
+ nullptr);
+
   // Emit a library call.
   TargetLowering::ArgListTy Args;
   TargetLowering::ArgListEntry Entry;
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -596,6 +596,10 @@
   if (!getCodeGenOpts().RecordCommandLine.empty())
 EmitCommandLineMetadata();
 
+  if (LangOpts.Freestanding) {
+getModule().addModuleFlag(llvm::Module::Override, "force-inline-libc", 1);
+  }
+
   EmitTargetMetadata();
 }
 


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5464,6 +5464,14 @@
   }
 }
 
+static bool IsForceInlineLibc(const SelectionDAG &DAG) {
+  const Module *M = DAG.getMachineFunction().getFunction().getParent();
+  if (auto *MD = mdconst::extract_or_null(
+  M->getModuleFlag("force-inline-libc")))
+return MD->getZExtValue();
+  return false;
+}
+
 /// Lower the call to the specified intrinsic function. If we want to emit this
 /// as a call to a named external function, return the name. Otherwise, lower it
 /// and return null.
@@ -5537,10 +5545,11 @@
 unsigned Align = MinAlign(DstAlign, SrcAlign);
 bool isVol = MCI.isVolatile();
 bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());
+bool IsAlwaysInline = IsForceInlineLibc(DAG);
 // FIXME: Support passing different dest/src alignments to the memcpy DAG
 // node.
 SDValue MC = DAG.getMemcpy(getRoot(), sdl, Op1, Op2, Op3, Align, isVol,
-   false, isTC,
+   IsAlwaysInline, isTC,
MachinePointerInfo(I.getArgOperand(0)),
MachinePointerInfo(I.getArgOperand(1)));
 updateDAGForMaybeTailCall(MC);
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6090,6 +6090,9 @@
   // beyond the given memory regions. But fixing this isn't easy, and most
   // people don't care.
 
+  assert(MF->getFunction().getParent()->getModuleFlag("force-inline-libc") ==
+ nullptr);
+
   // Emit a library call.
   TargetLowering::ArgListTy Args;
   TargetLowering::ArgListEntry Entry;
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModu

[PATCH] D60719: Demonstrate how to fix freestanding for memcpy

2019-04-16 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 195369.
gchatelet added a comment.

Add test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60719/new/

https://reviews.llvm.org/D60719

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/freestanding-disables-libc.c
  llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5480,6 +5480,14 @@
   }
 }
 
+static bool IsForceInlineLibc(const SelectionDAG &DAG) {
+  const Module *M = DAG.getMachineFunction().getFunction().getParent();
+  if (auto *MD = mdconst::extract_or_null(
+  M->getModuleFlag("force-inline-libc")))
+return MD->getZExtValue();
+  return false;
+}
+
 /// Lower the call to the specified intrinsic function. If we want to emit this
 /// as a call to a named external function, return the name. Otherwise, lower 
it
 /// and return null.
@@ -5553,10 +5561,11 @@
 unsigned Align = MinAlign(DstAlign, SrcAlign);
 bool isVol = MCI.isVolatile();
 bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());
+bool IsAlwaysInline = IsForceInlineLibc(DAG);
 // FIXME: Support passing different dest/src alignments to the memcpy DAG
 // node.
 SDValue MC = DAG.getMemcpy(getRoot(), sdl, Op1, Op2, Op3, Align, isVol,
-   false, isTC,
+   IsAlwaysInline, isTC,
MachinePointerInfo(I.getArgOperand(0)),
MachinePointerInfo(I.getArgOperand(1)));
 updateDAGForMaybeTailCall(MC);
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6090,6 +6090,9 @@
   // beyond the given memory regions. But fixing this isn't easy, and most
   // people don't care.
 
+  assert(MF->getFunction().getParent()->getModuleFlag("force-inline-libc") ==
+ nullptr);
+
   // Emit a library call.
   TargetLowering::ArgListTy Args;
   TargetLowering::ArgListEntry Entry;
Index: clang/test/CodeGen/freestanding-disables-libc.c
===
--- /dev/null
+++ clang/test/CodeGen/freestanding-disables-libc.c
@@ -0,0 +1,11 @@
+// NOTE: Test that IR module specifies a "force-inline-libc" attribute in 
freestanding mode.
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | not grep 
'force-inline-libc'
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O2 -emit-llvm %s -o - | not 
grep 'force-inline-libc'
+// RUN: %clang_cc1 -triple i386-unknown-unknown -ffreestanding -O2 -emit-llvm 
%s -o - | grep 'force-inline-libc'
+
+// NOTE: Test that assembly doesn't call memcpy function in freestanding mode.
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O2 -S %s -o - | grep 'memcpy'
+// RUN: %clang_cc1 -triple i386-unknown-unknown -ffreestanding -O2 -S %s -o - 
| not grep 'memcpy'
+
+struct BigStruct { char payload[4096]; };
+struct BigStruct PassByValue(struct BigStruct value) { return value; }
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -596,6 +596,10 @@
   if (!getCodeGenOpts().RecordCommandLine.empty())
 EmitCommandLineMetadata();
 
+  if (LangOpts.Freestanding) {
+getModule().addModuleFlag(llvm::Module::Override, "force-inline-libc", 1);
+  }
+
   EmitTargetMetadata();
 }
 


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5480,6 +5480,14 @@
   }
 }
 
+static bool IsForceInlineLibc(const SelectionDAG &DAG) {
+  const Module *M = DAG.getMachineFunction().getFunction().getParent();
+  if (auto *MD = mdconst::extract_or_null(
+  M->getModuleFlag("force-inline-libc")))
+return MD->getZExtValue();
+  return false;
+}
+
 /// Lower the call to the specified intrinsic function. If we want to emit this
 /// as a call to a named external function, return the name. Otherwise, lower it
 /// and return null.
@@ -5553,10 +5561,11 @@
 unsigned Align = MinAlign(DstAlign, SrcAlign);
 bool isVol = MCI.isVolatile();
 bool isTC = I.isTailCall() && isInTailCallPosition(&I, DAG.getTarget());
+bool IsAlwaysInline = IsForceInlineLibc(DAG);
 // FIXME: Support passing different dest/src alignments to the memcpy DAG
 // node.
 SDValue MC = DAG.getMemcpy(getRoot(), sdl, Op1, Op2, Op

[PATCH] D60719: Demonstrate how to fix freestanding for memcpy

2019-04-17 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D60719#1469958 , @t.p.northover 
wrote:

> I think it'd be pretty unpopular with the people I know who use freestanding. 
> They're mostly working on microcontrollers and compiling -Oz so the extra 
> code size would be untenable; they also have memcpy implementations anyway 
> because they use it in their own code.
>
> If I was trying to solve this (and I'm also not 100% sure it needs solving), 
> I think I'd instead generate a `linkonce` definition of `memcpy` whenever 
> it's needed and leave CodeGen unmodified.


Thx for chiming in @t.p.northover . Since the patch was mostly a proof of 
concept I haven't explained well what the intent was.
Ultimately I'm interested in implementing libc's mem function in C++. Let's 
take `memcpy` for instance, it would be composed out of fixed sized copies 
created from `__builtin_memcpy`. Unfortunately, the compiler is allowed to 
replace the intrinsic with a call to `memcpy` - which I'm currently defining - 
the generated code would recurse indefinitely.

IIUC //freestanding// environment should not rely on `memcpy` being present so 
my take on it was that by "fixing" //freestanding// I could have my cake and 
eat it too.

There are other options to explore but your comment shows that it's better to 
start a discussion around an RFC.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60719/new/

https://reviews.llvm.org/D60719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D60719: Demonstrate how to fix freestanding for memcpy

2019-04-18 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D60719#1470632 , @t.p.northover 
wrote:

> > IIUC freestanding environment should not rely on memcpy being present so my 
> > take on it was that by "fixing" freestanding I could have my cake and eat 
> > it too.
>
> The formal situation is that freestanding implementations are only required 
> to provide language support stuff like `va_list`. They're allowed to give 
> more of the standard library if they want though, as implementation defined 
> behaviour.
>
> In practice, everyone I know provides the basic `string.h` functions and the 
> compiler is pretty explicit about relying on them being present for 
> correctness. They're part of the surrounding environment a user is expected 
> to supply (much like the various exception handling callbacks if you want C++ 
> exceptions, but always required).
>
> For the people actually using freestanding I think they're mostly considered 
> important enough that they're implemented in assembly anyway so this isn't 
> really a burden, but...


Ack. "Fixing" freestanding is not the way to go then : )

>> Ultimately I'm interested in implementing libc's mem function in C++. Let's 
>> take memcpy for instance
> 
> Ah, that is an entirely different problem from what I thought you were trying 
> to do. In that case I'm all in favour of some solution, but would start 
> thinking along the lines of `-fno-builtin-memcpy` options (it's possible that 
> already does what you want, but can't get LLVM to form a `memcpy` from quick 
> tests to check).

Thx for taking the time to suggest possible solution, I really appreciate it.

I already tried `-fno-builtin-memcpy`. The semantic of this flag is pretty 
counter intuitive and I'll explain why it doesn't fit my needs.
LLVM is allowed to replace a piece of code that looks like a `memcpy` with an 
IR intrinsic that implements the same semantic. You can see this by inspecting 
the IR here: https://godbolt.org/z/0y1Yqh.
Now if you use `-fno-builtin-memcpy` you're preventing the compiler from 
understanding that this is a memory copy. Look at the IR here: 
https://godbolt.org/z/lnCIIh.
The vectorizer kicks in in this case and the generated code is quite good but 
sometimes the generated code is pretty bad: https://godbolt.org/z/mHpAYe.

Last but not least `-fno-builtin-memcpy`prevents the compiler from 
understanding code constructs as memcpy but does not prevent the compiler from 
generating calls to `memcpy`:

- Using `__builtin_memcpy` still lowers to `@llvm.memcpy` IR intrinsics: 
https://godbolt.org/z/O0sjIl
- Passing big structs by value will lowers to `@llvm.memcpy` IR intrinsics: 
https://godbolt.org/z/4BUDc0

Another solution is needed for my use case, either a new C++ intrinsics 
`__builtin_inline_memcpy` or an attribute that disables generated libc calls, 
compiler could either inline or fail with an error.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60719/new/

https://reviews.llvm.org/D60719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-07 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
gchatelet added a reviewer: courbet.
Herald added subscribers: llvm-commits, cfe-commits, mgrang, hiraditya.
Herald added projects: clang, LLVM.

POC for the rfc http://lists.llvm.org/pipermail/llvm-dev/2019-April/131973.html


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D61634

Files:
  clang/include/clang/Basic/Attr.td
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/IRBuilder.cpp
  llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
  llvm/test/CodeGen/X86/memcpy.ll

Index: llvm/test/CodeGen/X86/memcpy.ll
===
--- llvm/test/CodeGen/X86/memcpy.ll
+++ llvm/test/CodeGen/X86/memcpy.ll
@@ -7,7 +7,7 @@
 
 
 ; Variable memcpy's should lower to calls.
-define i8* @test1(i8* %a, i8* %b, i64 %n) nounwind {
+define void @test1(i8* %a, i8* %b, i64 %n) nounwind {
 ; LINUX-LABEL: test1:
 ; LINUX:   # %bb.0: # %entry
 ; LINUX-NEXT:jmp memcpy # TAILCALL
@@ -17,11 +17,11 @@
 ; DARWIN-NEXT:jmp _memcpy ## TAILCALL
 entry:
 	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 )
-	ret i8* %a
+  ret void
 }
 
 ; Variable memcpy's should lower to calls.
-define i8* @test2(i64* %a, i64* %b, i64 %n) nounwind {
+define void @test2(i64* %a, i64* %b, i64 %n) nounwind {
 ; LINUX-LABEL: test2:
 ; LINUX:   # %bb.0: # %entry
 ; LINUX-NEXT:jmp memcpy # TAILCALL
@@ -33,7 +33,25 @@
 	%tmp14 = bitcast i64* %a to i8*
 	%tmp25 = bitcast i64* %b to i8*
 	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %tmp14, i8* align 8 %tmp25, i64 %n, i1 0 )
-	ret i8* %tmp14
+  ret void
+}
+
+; Variable length memcpy's with disabled runtime should lower to repmovsb.
+define void @memcpy_no_runtime(i8* %a, i8* %b, i64 %n) nounwind {
+; LINUX-LABEL: memcpy_no_runtime:
+; LINUX:   # %bb.0: # %entry
+; LINUX-NEXT:movq %rdx, %rcx
+; LINUX-NEXT:rep;movsb (%rsi), %es:(%rdi)
+; LINUX-NEXT:retq
+;
+; DARWIN-LABEL: memcpy_no_runtime:
+; DARWIN:   ## %bb.0: ## %entry
+; DARWIN-NEXT:movq %rdx, %rcx
+; DARWIN-NEXT:rep;movsb (%rsi), %es:(%rdi)
+; DARWIN-NEXT:retq
+entry:
+	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 ) "no_runtime_for" = "memcpy"
+  ret void
 }
 
 ; Large constant memcpy's should lower to a call when optimizing for size.
Index: llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
===
--- llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -314,5 +314,9 @@
   Size.getValueType(), Align, isVolatile,
   AlwaysInline, DstPtrInfo, SrcPtrInfo);
 
+  /// Handle runtime sizes through repmovsb when we AlwaysInline.
+  if (AlwaysInline)
+return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src, Size, MVT::i8);
+
   return SDValue();
 }
Index: llvm/lib/IR/IRBuilder.cpp
===
--- llvm/lib/IR/IRBuilder.cpp
+++ llvm/lib/IR/IRBuilder.cpp
@@ -96,6 +96,17 @@
   return II;
 }
 
+static void ForwardNoRuntimeAttribute(const Function *F,
+ StringRef FunctionName,
+ CallInst *CI) {
+  if (F->hasFnAttribute("no_runtime_for")) {
+const Attribute A = F->getFnAttribute("no_runtime_for");
+if (A.getValueAsString().contains(FunctionName)) {
+  CI->addAttribute(AttributeList::FunctionIndex, A);
+}
+  }
+}
+
 CallInst *IRBuilderBase::
 CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
  bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
@@ -103,7 +114,8 @@
   Ptr = getCastedInt8PtrValue(Ptr);
   Value *Ops[] = {Ptr, Val, Size, getInt1(isVolatile)};
   Type *Tys[] = { Ptr->getType(), Size->getType() };
-  Module *M = BB->getParent()->getParent();
+  Function *F = BB->getParent();
+  Module *M = F->getParent();
   Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
 
   CallInst *CI = createCallHelper(TheFn, Ops, this);
@@ -121,6 +133,8 @@
   if (NoAliasTag)
 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
 
+  ForwardNoRuntimeAttribute(F, "memset", CI);
+
   return CI;
 }
 
@@ -165,7 +179,8 @@
 
   Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
-  Module *M = BB->getParent()->getParent();
+  Function *F = BB->getParent();
+  Module *M = F->getParent();
   Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
 
   CallInst *CI = createCallHelper(TheFn, Ops, this);
@@ -190,6 +205,8 @@
   if (NoAliasTag)
 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
 
+  ForwardNoRuntimeAttribute(F, "memcpy", CI);
+
   return CI;
 }
 
@@ -245,7 +262,8 @@
 
   Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
   T

[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-07 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 198436.
gchatelet added a comment.
Herald added a subscriber: jdoerfert.

- Add documentation.
- Fix permissive HasNoRuntimeAttribute


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/IRBuilder.cpp
  llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
  llvm/test/CodeGen/X86/memcpy.ll

Index: llvm/test/CodeGen/X86/memcpy.ll
===
--- llvm/test/CodeGen/X86/memcpy.ll
+++ llvm/test/CodeGen/X86/memcpy.ll
@@ -7,7 +7,7 @@
 
 
 ; Variable memcpy's should lower to calls.
-define i8* @test1(i8* %a, i8* %b, i64 %n) nounwind {
+define void @test1(i8* %a, i8* %b, i64 %n) nounwind {
 ; LINUX-LABEL: test1:
 ; LINUX:   # %bb.0: # %entry
 ; LINUX-NEXT:jmp memcpy # TAILCALL
@@ -17,11 +17,11 @@
 ; DARWIN-NEXT:jmp _memcpy ## TAILCALL
 entry:
 	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 )
-	ret i8* %a
+  ret void
 }
 
 ; Variable memcpy's should lower to calls.
-define i8* @test2(i64* %a, i64* %b, i64 %n) nounwind {
+define void @test2(i64* %a, i64* %b, i64 %n) nounwind {
 ; LINUX-LABEL: test2:
 ; LINUX:   # %bb.0: # %entry
 ; LINUX-NEXT:jmp memcpy # TAILCALL
@@ -33,7 +33,25 @@
 	%tmp14 = bitcast i64* %a to i8*
 	%tmp25 = bitcast i64* %b to i8*
 	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %tmp14, i8* align 8 %tmp25, i64 %n, i1 0 )
-	ret i8* %tmp14
+  ret void
+}
+
+; Variable length memcpy's with disabled runtime should lower to repmovsb.
+define void @memcpy_no_runtime(i8* %a, i8* %b, i64 %n) nounwind {
+; LINUX-LABEL: memcpy_no_runtime:
+; LINUX:   # %bb.0: # %entry
+; LINUX-NEXT:movq %rdx, %rcx
+; LINUX-NEXT:rep;movsb (%rsi), %es:(%rdi)
+; LINUX-NEXT:retq
+;
+; DARWIN-LABEL: memcpy_no_runtime:
+; DARWIN:   ## %bb.0: ## %entry
+; DARWIN-NEXT:movq %rdx, %rcx
+; DARWIN-NEXT:rep;movsb (%rsi), %es:(%rdi)
+; DARWIN-NEXT:retq
+entry:
+	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 ) "no_runtime_for" = "memcpy"
+  ret void
 }
 
 ; Large constant memcpy's should lower to a call when optimizing for size.
Index: llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
===
--- llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -314,5 +314,9 @@
   Size.getValueType(), Align, isVolatile,
   AlwaysInline, DstPtrInfo, SrcPtrInfo);
 
+  /// Handle runtime sizes through repmovsb when we AlwaysInline.
+  if (AlwaysInline)
+return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src, Size, MVT::i8);
+
   return SDValue();
 }
Index: llvm/lib/IR/IRBuilder.cpp
===
--- llvm/lib/IR/IRBuilder.cpp
+++ llvm/lib/IR/IRBuilder.cpp
@@ -96,6 +96,17 @@
   return II;
 }
 
+static void ForwardNoRuntimeAttribute(const Function *F,
+ StringRef FunctionName,
+ CallInst *CI) {
+  if (F->hasFnAttribute("no_runtime_for")) {
+const Attribute A = F->getFnAttribute("no_runtime_for");
+if (A.getValueAsString().contains(FunctionName)) {
+  CI->addAttribute(AttributeList::FunctionIndex, A);
+}
+  }
+}
+
 CallInst *IRBuilderBase::
 CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
  bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
@@ -103,7 +114,8 @@
   Ptr = getCastedInt8PtrValue(Ptr);
   Value *Ops[] = {Ptr, Val, Size, getInt1(isVolatile)};
   Type *Tys[] = { Ptr->getType(), Size->getType() };
-  Module *M = BB->getParent()->getParent();
+  Function *F = BB->getParent();
+  Module *M = F->getParent();
   Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
 
   CallInst *CI = createCallHelper(TheFn, Ops, this);
@@ -121,6 +133,8 @@
   if (NoAliasTag)
 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
 
+  ForwardNoRuntimeAttribute(F, "memset", CI);
+
   return CI;
 }
 
@@ -165,7 +179,8 @@
 
   Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
-  Module *M = BB->getParent()->getParent();
+  Function *F = BB->getParent();
+  Module *M = F->getParent();
   Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
 
   CallInst *CI = createCallHelper(TheFn, Ops, this);
@@ -190,6 +205,8 @@
   if (NoAliasTag)
 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
 
+  ForwardNoRuntimeAttribute(F, "memcpy", CI);
+
   return CI;
 }
 
@@ -245,7 +262,8 @@
 
   Value *Ops[] = {Dst, Src, Size, getIn

[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-07 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D61634#1493350 , @theraven wrote:

> I wonder if a list of comma-separated names is the right approach.  Would it 
> make more sense to add a new attribute for each of the helpers, such as 
> `#no-runtime-for-memcpy`? That should make querying simpler (one lookup in 
> the table, rather than a lookup and a string scan) and also make it easier to 
> add and remove attributes (merging is now just a matter of trying to add all 
> of them, with the existing logic to deduplicate repeated attributes working).


So I decided to go that route for two reasons:

- The `no_runtime_for` attribute will be used almost exclusively by runtime 
implementers, on average lookup will return false and the parsing part should 
be marginal (famous last words?)
- We need to support every function in TargetLibraryInfo 

 (I count 434 of them) and I'm not sure adding one attribute per function will 
scale or can stay in sync.

Now I haven't thought about merging indeed, we may be able to reuse or clone 
the approach used for `target-features`?
For instance some backend disable specific functions and we may warn the user 
if it happens. e.g. `setLibcallName(RTLIB::SHL_I128, nullptr);` in 
X86ISelLowering.cpp 


I'm not saying one attribute per helper is not feasible but I'd like to put it 
into perspective with other constraints.

> We probably need to also carefully audit all of the transform passes to find 
> ones that insert calls.  Last time I looked, there were four places in LLVM 
> where memcpy could be expanded, I wonder if there are a similar number where 
> it can be synthesised...

Yes indeed, it's going to be long and painful, here are the functions calling 
`CallLoweringInfo::setLibCallee` :

**llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp**

- ExpandLibCall(LC, Node, isSigned)
- ExpandChainLibCall(LC, Node, isSigned)
- ExpandDivRemLibCall(Node, Results)
- ExpandSinCosLibCall(Node, Results)
- ConvertNodeToLibcall(Node)
- ConvertNodeToLibcall(Node)

**llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp**

- ExpandIntRes_XMULO(N, Lo, Hi)

**llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp**

- ExpandChainLibCall(LC, Node, isSigned)

**llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp**

- getMemcpy(Chain, dl, Dst, Src, Size, Align, isVol, AlwaysInline, isTailCall, 
DstPtrInfo, SrcPtrInfo)
- getAtomicMemcpy(Chain, dl, Dst, DstAlign, Src, SrcAlign, Size, SizeTy, 
ElemSz, isTailCall, DstPtrInfo, SrcPtrInfo)
- getMemmove(Chain, dl, Dst, Src, Size, Align, isVol, isTailCall, DstPtrInfo, 
SrcPtrInfo)
- getAtomicMemmove(Chain, dl, Dst, DstAlign, Src, SrcAlign, Size, SizeTy, 
ElemSz, isTailCall, DstPtrInfo, SrcPtrInfo)
- getMemset(Chain, dl, Dst, Src, Size, Align, isVol, isTailCall, DstPtrInfo)
- getAtomicMemset(Chain, dl, Dst, DstAlign, Value, Size, SizeTy, ElemSz, 
isTailCall, DstPtrInfo)

**llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp**

- visitIntrinsicCall(I, Intrinsic)

**llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp**

- makeLibCall(DAG, LC, RetVT, Ops, isSigned, dl, doesNotReturn, 
isReturnValueUsed, isPostTypeLegalization)
- LowerToTLSEmulatedModel(GA, DAG)

**llvm/lib/Target/AArch64/AArch64ISelLowering.cpp**

- LowerFSINCOS(Op, DAG)

**llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp**

- EmitTargetCodeForMemset(DAG, dl, Chain, Dst, Src, Size, Align, isVolatile, 
DstPtrInfo)

**llvm/lib/Target/ARM/ARMISelLowering.cpp**

- LowerToTLSGeneralDynamicModel(GA, DAG)

**llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp**

- EmitSpecializedLibcall(DAG, dl, Chain, Dst, Src, Size, Align, LC)

**llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp**

- EmitTargetCodeForMemcpy(DAG, dl, Chain, Dst, Src, Size, Align, isVolatile, 
AlwaysInline, DstPtrInfo, SrcPtrInfo)

**llvm/lib/Target/PowerPC/PPCISelLowering.cpp**

- LowerINIT_TRAMPOLINE(Op, DAG)

**llvm/lib/Target/X86/X86ISelLowering.cpp**

- LowerWin64_i128OP(Op, DAG)
- LowerFSINCOS(Op, Subtarget, DAG)

**llvm/lib/Target/X86/X86SelectionDAGInfo.cpp**

- EmitTargetCodeForMemset(DAG, dl, Chain, Dst, Val, Size, Align, isVolatile, 
DstPtrInfo)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-06-06 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 203386.
gchatelet added a comment.

- Add documentation.
- Fix permissive HasNoRuntimeAttribute
- Mark interleave as disabled in the documentation.
- Use no-builtin instead of no-runtime-for.
- Adding an llvm.memcpy.inline intrinsic.
- Adding __builtin_memcpy_inline clang builtin.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuilder.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/IntrinsicInst.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/IRBuilder.cpp
  llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
  llvm/test/CodeGen/X86/memcpy-inline.ll
  llvm/test/CodeGen/X86/memcpy.ll

Index: llvm/test/CodeGen/X86/memcpy.ll
===
--- llvm/test/CodeGen/X86/memcpy.ll
+++ llvm/test/CodeGen/X86/memcpy.ll
@@ -7,7 +7,7 @@
 
 
 ; Variable memcpy's should lower to calls.
-define i8* @test1(i8* %a, i8* %b, i64 %n) nounwind {
+define void @test1(i8* %a, i8* %b, i64 %n) nounwind {
 ; LINUX-LABEL: test1:
 ; LINUX:   # %bb.0: # %entry
 ; LINUX-NEXT:jmp memcpy # TAILCALL
@@ -17,11 +17,11 @@
 ; DARWIN-NEXT:jmp _memcpy ## TAILCALL
 entry:
 	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 )
-	ret i8* %a
+  ret void
 }
 
 ; Variable memcpy's should lower to calls.
-define i8* @test2(i64* %a, i64* %b, i64 %n) nounwind {
+define void @test2(i64* %a, i64* %b, i64 %n) nounwind {
 ; LINUX-LABEL: test2:
 ; LINUX:   # %bb.0: # %entry
 ; LINUX-NEXT:jmp memcpy # TAILCALL
@@ -33,7 +33,25 @@
 	%tmp14 = bitcast i64* %a to i8*
 	%tmp25 = bitcast i64* %b to i8*
 	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %tmp14, i8* align 8 %tmp25, i64 %n, i1 0 )
-	ret i8* %tmp14
+  ret void
+}
+
+; Variable length memcpy's with disabled runtime should lower to repmovsb.
+define void @memcpy_no_runtime(i8* %a, i8* %b, i64 %n) nounwind {
+; LINUX-LABEL: memcpy_no_runtime:
+; LINUX:   # %bb.0: # %entry
+; LINUX-NEXT:movq %rdx, %rcx
+; LINUX-NEXT:rep;movsb (%rsi), %es:(%rdi)
+; LINUX-NEXT:retq
+;
+; DARWIN-LABEL: memcpy_no_runtime:
+; DARWIN:   ## %bb.0: ## %entry
+; DARWIN-NEXT:movq %rdx, %rcx
+; DARWIN-NEXT:rep;movsb (%rsi), %es:(%rdi)
+; DARWIN-NEXT:retq
+entry:
+	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 ) "no-builtin-memcpy"
+  ret void
 }
 
 ; Large constant memcpy's should lower to a call when optimizing for size.
Index: llvm/test/CodeGen/X86/memcpy-inline.ll
===
--- /dev/null
+++ llvm/test/CodeGen/X86/memcpy-inline.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=core2 | FileCheck %s
+
+declare void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
+
+define void @test1(i8* %a, i8* %b) nounwind {
+; CHECK-LABEL: test1:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:movq (%rsi), %rax
+; CHECK-NEXT:movq %rax, (%rdi)
+; CHECK-NEXT:retq
+	tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* %a, i8* %b, i64 8, i1 0 )
+  ret void
+}
Index: llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
===
--- llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -314,5 +314,9 @@
   Size.getValueType(), Align, isVolatile,
   AlwaysInline, DstPtrInfo, SrcPtrInfo);
 
+  /// Handle runtime sizes through repmovsb when we AlwaysInline.
+  if (AlwaysInline)
+return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src, Size, MVT::i8);
+
   return SDValue();
 }
Index: llvm/lib/IR/IRBuilder.cpp
===
--- llvm/lib/IR/IRBuilder.cpp
+++ llvm/lib/IR/IRBuilder.cpp
@@ -96,6 +96,14 @@
   return II;
 }
 
+static void ForwardAttribute(const Function *F, StringRef Attribute,
+ CallInst *CI) {
+  if (F->hasFnAttribute(Attribute)) {
+CI->addAttribute(AttributeList::FunctionIndex,
+ F->getFnAttribute(Attribute));
+  }
+}
+
 CallInst *IRBuilderBase::
 CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
  bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
@@ -103,7 +111,8 @@
   Ptr = getCastedInt8PtrValue(Ptr);
   Value *Ops[] = {Ptr, Val, Size, getInt1(isVolatile)};
   Type *Tys[] = { Ptr->getType(), Size->getType() };
-  Module *M = BB->getParent()->getParent(

[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-07-16 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D61634#1586047 , @tejohnson wrote:

> Checking in to see where we are on this issue. I haven't had any time to work 
> on 4 but hopefully can start on that soon. But it needs the first part done 
> to be effective.


Thx for the heads up @tejohnson.
The patch is missing a bit of documentation but it shouldn't be too far from 
complete:

- it adds a clang function attribute, e.g. 
`__attribute__((no_builtin("memcpy")))`
- instructs clang to compose individual IR attributes from the clang attribute 
above, e.g. `no-builtin-memcpy`, `no-builtin-memset`, `no-builtin-sqrt`...
- adds a specific builtin to clang for the memcpy case `__builtin_memcpy_inline`
- adds an LLVM IR intrinsic `int_memcpy_inline`
- adds an LLVM Instruction `MemCpyInlineInst`
- instructs LLVM to forward the `no-builtin-memcpy` IR attribute from the 
function declaration to the actual memcpy calls inside the function's body 
(same for `memset` and `memmove`)
- adds code to turn the `MemCpyInlineInst` into code, using `DAG.getMemcpy` 
with `always_inline` set.

Left to do:

- finish implementing memset / memmove
- check attributes and reject the one that are not implemented
- add documentation

There's too many things going on in this patch and it may worth splitting it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-10 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D61634#1493927 , @efriedma wrote:

> I would be careful about trying to over-generalize here.  There are a few 
> different related bits of functionality which seem to be interesting, given 
> the discussion in the llvm-dev thread, here, and in related patches:


Thx for the feedback @efriedma, I don't fully understand what you're suggesting 
here so I will try to reply inline.

> 1. The ability to specify -fno-builtin* on a per-function level, using 
> function attributes.

`-fno-builtin*` is about preventing clang/llvm from recognizing that a piece of 
code has the same semantic as a particular IR intrinsic, it has nothing to do 
with preventing the compiler from generating runtime calls.

- `fno-builtin` is about transformation from code to IR (frontend)
- The RFC is about the transformation from IR to runtime calls (backend)

> 2. Improved optimization when -fno-builtin-memcpy is specified.

I don't see this happening because if `-fno-builtin-memcpy`is used, clang 
(frontend) might already have unrolled and vectorized the loop, It is then very 
hard - by simply looking at the IR - to recognize that it's a `memcpy` and 
generate good code (e.g. https://godbolt.org/z/JZ-mR0)
Here we really want the compiler to understand that we are copying memory (i.e. 
this is really `@llvm.memcpy` semantic) but we want to prevent it from calling 
the runtime.

> 3. The ability to avoid calls to memcpy for certain C constructs which would 
> naturally be lowered to a memcpy call, like struct assignment of large 
> structs, or explicit calls to __builtin_memcpy().  Maybe also some 
> generalization of this involving other libc/libm/compiler-rt calls.

I believe very few people will use the attribute described in the RFC, it will 
most probably be library maintainers that already know a good deal of how the 
compiler is allowed to transform the code.

> 4. The ability to force the compiler to generate "rep; movs" on x86 without 
> inline asm.

This is not strictly required - at least this is not too useful from the 
purpose of building memcpy functions (more on this a few lines below).

> It's not clear to me that all of this should be tied together.  In 
> particular, I'm not sure -fno-builtin-memcpy should imply the compiler never 
> generates a call to memcpy().

As a matter of fact, those are not tied together. There are different use cases 
with different solutions, the one I'm focusing on here is about preventing the 
compiler from synthesizing runtime calls because we want to be able to 
implement them directly from C / C++.
It is orthogonal to having the compiler recognize a piece of code as an IR 
intrinsic.

> On recent x86 chips, you might be able to get away with unconditionally using 
> "rep movs", but generally an efficient memcpy for more than a few bytes is a 
> lot longer than one instruction, and is not something reasonable for the 
> compiler to synthesize inline.

Well it depends. On Haswell and particularly Skylake it's hard to beat 
rep;movsb for anything bigger than 1k, be it aligned or not.
On other architectures and especially on the ones without ERMSB you have 
different strategies. Actually this is the very goal of this RFC: if you can 
inline or use PGO you can do a much better job for small sizes than calling 
libc's memcpy or inserting `rep;movsb`.

> If we're adding new IR attributes here, we should also consider the 
> interaction with LTO.

Yes this is a very different story, that's why I'm not exploring this route. 
It's rather possible that it would come with a high maintenance cost as well.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-10 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D61634#1494518 , @alexandre.isoard 
wrote:

> I'm not convinced by the approach.
>
> Can it still recognize the loop idiom into memcpy implementation but use 
> `memmove` (as only `memcpy` has been blacklisted)?


Yes it can and it's fine, passing `src` and `dst` arguments as `__restrict` 
will ensure that `memcpy` is the function to choose in this case.
This attribute is not to be used widely but is directed towards library 
maintainer that already know what the compiler is allowed to do.

> Can it do the same for `memmove` (for the case without overlap), and end-up 
> with infinite recursion?

I fail to see how this would happen. Could you craft some pseudo code that 
would exhibit the infinite recursion?
My take on it is that if the compiler can't generate the code it's totally OK 
to fail with an error message.

The purpose of this RFC it to get some help from the compiler to generate the 
best code for some building blocks (say `copy 4 bytes`, `copy 8 bytes`) and 
assemble them in a way that maximizes something (code size, runtime for certain 
parameter distributions).
It would be useful only to libc / libm / compiler-rt implementers to build 
these functions on top of smaller functions that we know the compiler can 
produce at compile time.

I don't think we want to use this attribute to generate fully the `memcpy`. I 
added the expansion into a `rep;movsb` for variable sized memcpy only because 
it's feasible on x86. It's preferable in this case since it has the correct 
semantic and prevents a compilation error but I would be fine with a 
compilation error here.

> I have a feeling we should pick a stance:
> 
> - either not allow the compiler to lower a builtin to a call to the library; 
> (my preferred choice, but I'm biased)

From the point of view of LLVM `@llvm.memcpy` intrinsics has the semantic of 
`memcpy` it does not know if it comes from a lowering in the frontend (e.g. 
passing structures by value) or from a built in. 
I believe this is feasible although I fail to see where my proposal falls 
short. Can you show a code example where the current proposal is problematic?

> - or not allow the library to use compiler builtins (but LTO flow with the 
> runtime library *already* linked smells like trouble if we go this way).

This is currently generating very poor code because `-fno-builtin` prevents 
LLVM from understanding the copy semantic.

> The reason for my bias is that I have a multi-memcpy codegen in the compiler 
> to generate those two calls:
> 
>   memcpy(left,  in, n);
>   memcpy(right, in, n);
> 
> 
> with a single loop.

I don't quite understand how this is linked to the issue at hand. Can you 
provide more context? Pointers to code?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-13 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D61634#1498376 , @efriedma wrote:

> I still think there are really two things you're trying to accomplish here, 
> which should be handled separately.
>
> 1. Add a function attribute that works like -fno-builtin-memcpy currently 
> does, to prevent the compiler from synthesizing calls to memcpy.
> 2. Provide a convenient way to write a small, fixed-length "memcpy", in C and 
> in LLVM IR, that is always expanded to optimal straight-line code (without 
> any calls or loops).
>
>   These correspond to proposals (1) and (2) from your RFC; I think we need 
> both to arrive at a reasonable final state.
>
>   (The "rep; movs" is a third thing, which I think should also be handled 
> separately, but it sounds like you don't think that's very important.)


Thank you for taking the time to comment, your feedback is highly appreciated.

I understand that your main concern is about conflating two orthogonal 
requirements (namely 1. and 2.) in a single attribute. Is that correct?
From my point of view, the RFC (and this Patch) really is about 1. - because 2. 
can already be achieved with builtins `__builtin_memcpy(dst, src, )`.

My secondary goals in decreasing priority order are:

- do not change the semantic of current builtins,
- create a relatively straightforward LLVM patch that does not touch too much 
code and that is easy review,
- do not add more confusion around `-fno-builtin-*` meaning,
- do not add more builtins or IR intrinsics.

What is the main blocker on your end? What would you suggest so we can move 
forward?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-14 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a subscriber: tejohnson.
gchatelet added a comment.

In D61634#1500453 , @efriedma wrote:

> My main blocker is that I want to make sure we're moving in the right 
> direction: towards LLVM IR with clear semantics, towards straightforward 
> rules for writing freestanding C code, and towards solutions which behave 
> appropriately for all targets.  There's clearly a problem here that's worth 
> solving, but I want to make sure we're adding small features that interact 
> with existing features in an obvious way.  The patch as written is adding a 
> new attribute that changes the semantics of C and LLVM IR in a subtle way 
> that interacts with existing optimizations and lowering in ways that are 
> complex and hard to understand.


This makes a lot of sense, I'm totally on board to reduce entropy and confusion 
along the way.

> I don't want to mix general restrictions on calling C library functions, with 
> restrictions that apply specifically to memcpy: clang generally works on the 
> assumption that a "memcpy" symbol is available in freestanding environments, 
> and we don't really want to change that.
> 
> With -fno-builtin, specifically, we currently apply the restriction that 
> optimizations will not introduce memcpy calls that would not exist with 
> optimization disabled.  This is sort of artificial, and and maybe a bit 
> confusing, but it seems to work well enough in practice.  gcc does something 
> similar.
> 
> I don't really want to add an attribute that has a different meaning from 
> -fno-builtin.  An attribute that has the same meaning is a lot less 
> problematic: it reduces potential confusion, and solves a related problem 
> that -fno-builtin currently doesn't really work with LTO, because we don't 
> encode it into the IR.

Adding @tejohnson to the conversation.

IIUC you're offering to introduce something like 
`__attribute__((no-builtin-memcpy))` or `__attribute__((no-builtin("memcpy")))`.
As attributes they would compose nicely with (Thin)LTO.

I believe we still want to turn `-fno-builtin` flags into attributes so there's 
no impedance mismatch between the flag and the attribute right?

> Your current patch is using the "AlwaysInline" flag for 
> SelectionDAG::getMemcpy, which forces a memcpy to be lowered to an inline 
> implementation.  In general, this flag is only supported for constant-size 
> memcpy calls; otherwise, on targets where EmitTargetCodeForMemcpy does not 
> have some special lowering, like the x86 "rep;movs", you'll hit an assertion 
> failure.  And we don't really want to add an implementation of 
> variable-length memcpy for a lot of targets; it's very inefficient on targets 
> which don't have unaligned memory access.  You could try to narrowly fix this 
> to only apply "AlwaysInline" if the size is a constant integer, but there's a 
> related problem: even if a memcpy is constant size in C, optimizations don't 
> promise to preserve that, in general.  We could theoretically add such a 
> promise, I guess, but that's awkward: it would conditionally apply to 
> llvm.memcpy where the parameter is already const, so it's not something we 
> can easily verify.

Fair enough. This patch was really to get the conversation started : I was 
myself not especially convinced about the approach. Hijacking the 
`AlwaysInline` parameter was a shortcut that would not work for other mem 
function anyways.

> If we added a new builtin `llvm.memcpy.inline`, or something like that, the 
> end result ends up being simpler in many ways. It has obvious rules for both 
> generating it and lowering it, which don't depend on attributes in the parent 
> function.  We could mark the size as "immarg", so we don't have to add 
> special optimization rules for it.   And if we have it, we have a "complete" 
> solution for writing memcpy implementations in C: we make `__builtin_memcpy`, 
> or a new `__builtin_inline_memcpy`, produce it, and it can be combined with 
> -fno-builtin to ensure we don't produce any calls to the "real" memcpy.  The 
> downside of a new builtin, of course, is that we now have two functions with 
> similar semantics, and potentially have to fix a bunch of places to check for 
> both of them.

This was one of the approaches I envisioned, it's much cleaner and it's also a 
lot more work : )
I'm willing to go that route knowing that it would also work for @theraven's 
use case.

> MemCpyOpt has been mentioned (the pass which transforms memcpy-like loops 
> into llvm.memcpy).  If we want it to perform some transform in circumstances 
> where the call "memcpy" isn't available, we have to make sure to restrict it 
> based on the target: in the worst case, on some targets without unaligned 
> memory access, it could just act as a low-quality loop unroller.  This 
> applies no matter how the result is actually represented in IR.

Yes if we have to generate loops it need to happen before SelectionDAG.



In this frame

[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-15 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D61634#1502201 , @tejohnson wrote:

> Using function level attributes instead of module flags does provide finer 
> grained control and avoids the conservativeness when merging IR for LTO. The 
> downsides I see, mostly just in terms of the engineering effort to get this 
> to work, are:
>
> - need to prevent inlining with different attributes


IIUC this is needed regardless of the proposed change. Correct?

> - currently the TargetLibraryInfo is constructed on a per-module basis. 
> Presumably it would instead need to be created per Function - this one in 
> particular seems like it would require fairly extensive changes.

Yes this one is a bit worrying.
I think we can discard right away any solution that would mutate or creating a 
TLI on a per function basis.
Another design could be the following:

  auto FunctionTLI = ModuleTLI.createCustomizedTLI(F);

`FunctionTLI` would either return the function customizations or delegate to 
the modules TLI. WDYT?

I'm unsure if we want to support function level attribute right away or if it's 
OK to be in an intermediate state with only module level attributes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-22 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

AFAIU here is a coarse plan of what needs to happen

1. Add a `no-builtin` clang function attribute that has the same semantic as 
the `no-builtin` cmd line argument 

2. Propagate it to the IR.
  - In the light of recent discussions and as @theraven suggested it seems more 
appropriate to encode them as individual IR attributes (e.g. 
`"no-builtin-memcpy"`, `"no-builtin-sqrt"`, etc..)
3. Propagate/merge the `no-builtin` IR attribute for LTO by "updating 
`AttributeFuncs::areInlineCompatible` and/or 
`AttributeFuncs::mergeAttributesForInlining` and adding a new MergeRule in 
`include/llvm/IR/Attributes.td` and writing a function like 
`adjustCallerStackProbeSize`."
4. Get inspiration from `TargetTransformInfo` to get `TargetLibraryInfo` on a 
per function basis for all passes and respect the IR attribute.

I'm not familiar with 3 and 4 but I can definitely have a look.
I'll update this patch to do 1 and 2 in the meantime. @tejohnson let me know 
how you want to proceed for your related patch 
. I'm happy to help if I can.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-05-23 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 200998.
gchatelet added a comment.

- Use no-builtin instead of no-runtime-for.
- Use one attribute per runtime function to make merging easier.

The patch is still WIP and needs more work.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/IRBuilder.cpp
  llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
  llvm/test/CodeGen/X86/memcpy.ll

Index: llvm/test/CodeGen/X86/memcpy.ll
===
--- llvm/test/CodeGen/X86/memcpy.ll
+++ llvm/test/CodeGen/X86/memcpy.ll
@@ -7,7 +7,7 @@
 
 
 ; Variable memcpy's should lower to calls.
-define i8* @test1(i8* %a, i8* %b, i64 %n) nounwind {
+define void @test1(i8* %a, i8* %b, i64 %n) nounwind {
 ; LINUX-LABEL: test1:
 ; LINUX:   # %bb.0: # %entry
 ; LINUX-NEXT:jmp memcpy # TAILCALL
@@ -17,11 +17,11 @@
 ; DARWIN-NEXT:jmp _memcpy ## TAILCALL
 entry:
 	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 )
-	ret i8* %a
+  ret void
 }
 
 ; Variable memcpy's should lower to calls.
-define i8* @test2(i64* %a, i64* %b, i64 %n) nounwind {
+define void @test2(i64* %a, i64* %b, i64 %n) nounwind {
 ; LINUX-LABEL: test2:
 ; LINUX:   # %bb.0: # %entry
 ; LINUX-NEXT:jmp memcpy # TAILCALL
@@ -33,7 +33,25 @@
 	%tmp14 = bitcast i64* %a to i8*
 	%tmp25 = bitcast i64* %b to i8*
 	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %tmp14, i8* align 8 %tmp25, i64 %n, i1 0 )
-	ret i8* %tmp14
+  ret void
+}
+
+; Variable length memcpy's with disabled runtime should lower to repmovsb.
+define void @memcpy_no_runtime(i8* %a, i8* %b, i64 %n) nounwind {
+; LINUX-LABEL: memcpy_no_runtime:
+; LINUX:   # %bb.0: # %entry
+; LINUX-NEXT:movq %rdx, %rcx
+; LINUX-NEXT:rep;movsb (%rsi), %es:(%rdi)
+; LINUX-NEXT:retq
+;
+; DARWIN-LABEL: memcpy_no_runtime:
+; DARWIN:   ## %bb.0: ## %entry
+; DARWIN-NEXT:movq %rdx, %rcx
+; DARWIN-NEXT:rep;movsb (%rsi), %es:(%rdi)
+; DARWIN-NEXT:retq
+entry:
+	tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 %n, i1 0 ) "no-builtin-memcpy"
+  ret void
 }
 
 ; Large constant memcpy's should lower to a call when optimizing for size.
Index: llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
===
--- llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -314,5 +314,9 @@
   Size.getValueType(), Align, isVolatile,
   AlwaysInline, DstPtrInfo, SrcPtrInfo);
 
+  /// Handle runtime sizes through repmovsb when we AlwaysInline.
+  if (AlwaysInline)
+return emitRepmovs(Subtarget, DAG, dl, Chain, Dst, Src, Size, MVT::i8);
+
   return SDValue();
 }
Index: llvm/lib/IR/IRBuilder.cpp
===
--- llvm/lib/IR/IRBuilder.cpp
+++ llvm/lib/IR/IRBuilder.cpp
@@ -96,6 +96,14 @@
   return II;
 }
 
+static void ForwardAttribute(const Function *F, StringRef Attribute,
+ CallInst *CI) {
+  if (F->hasFnAttribute(Attribute)) {
+CI->addAttribute(AttributeList::FunctionIndex,
+ F->getFnAttribute(Attribute));
+  }
+}
+
 CallInst *IRBuilderBase::
 CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
  bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
@@ -103,7 +111,8 @@
   Ptr = getCastedInt8PtrValue(Ptr);
   Value *Ops[] = {Ptr, Val, Size, getInt1(isVolatile)};
   Type *Tys[] = { Ptr->getType(), Size->getType() };
-  Module *M = BB->getParent()->getParent();
+  Function *F = BB->getParent();
+  Module *M = F->getParent();
   Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
 
   CallInst *CI = createCallHelper(TheFn, Ops, this);
@@ -121,6 +130,8 @@
   if (NoAliasTag)
 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
 
+  ForwardAttribute(F, "no-builtin-memset", CI);
+
   return CI;
 }
 
@@ -165,7 +176,8 @@
 
   Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
-  Module *M = BB->getParent()->getParent();
+  Function *F = BB->getParent();
+  Module *M = F->getParent();
   Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
 
   CallInst *CI = createCallHelper(TheFn, Ops, this);
@@ -190,6 +202,8 @@
   if (NoAliasTag)
 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
 
+  ForwardAttribute(F, "no-builtin-memcpy", CI);
+
   return CI;
 }
 
@@ -245,7 +259,8 @@
 
   Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
-  Module *M = BB->getParent

[PATCH] D67499: [Alignment] Move OffsetToAlignment to Alignment.h

2019-09-12 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
gchatelet added a reviewer: courbet.
Herald added subscribers: llvm-commits, cfe-commits, seiya, jsji, atanasyan, 
MaskRay, jrtc27, jakehehrlich, kbarton, hiraditya, nemanjai, sdardis.
Herald added a reviewer: JDevlieghere.
Herald added a reviewer: alexshap.
Herald added a reviewer: rupprecht.
Herald added a reviewer: jhenderson.
Herald added projects: clang, LLVM.

This is patch is part of a series to introduce an Alignment type.
See this thread for context: 
http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html
See this patch for the introduction of the type: https://reviews.llvm.org/D64790


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D67499

Files:
  clang/lib/AST/DeclBase.cpp
  llvm/include/llvm/Support/Alignment.h
  llvm/include/llvm/Support/MathExtras.h
  llvm/include/llvm/Support/OnDiskHashTable.h
  llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
  llvm/lib/CodeGen/BranchRelaxation.cpp
  llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
  llvm/lib/MC/ELFObjectWriter.cpp
  llvm/lib/MC/MCAssembler.cpp
  llvm/lib/MC/MachObjectWriter.cpp
  llvm/lib/Object/ArchiveWriter.cpp
  llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
  llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
  llvm/lib/Target/Mips/MipsConstantIslandPass.cpp
  llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
  llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
  llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
  llvm/tools/dsymutil/DwarfStreamer.cpp
  llvm/tools/llvm-cov/TestingSupport.cpp
  llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp

Index: llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
===
--- llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
+++ llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
@@ -7,6 +7,7 @@
 //===--===//
 
 #include "MachOLayoutBuilder.h"
+#include "llvm/Support/Alignment.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -145,7 +146,7 @@
   Sec.Offset = 0;
 } else {
   uint64_t PaddingSize =
-  OffsetToAlignment(SegFileSize, 1ull << Sec.Align);
+  offsetToAlignment(SegFileSize, llvm::Align(1ull << Sec.Align));
   Sec.Offset = SegOffset + SegFileSize + PaddingSize;
   Sec.Size = Sec.Content.size();
   SegFileSize += PaddingSize + Sec.Size;
Index: llvm/tools/llvm-cov/TestingSupport.cpp
===
--- llvm/tools/llvm-cov/TestingSupport.cpp
+++ llvm/tools/llvm-cov/TestingSupport.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Alignment.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/raw_ostream.h"
@@ -99,7 +100,7 @@
   encodeULEB128(ProfileNamesAddress, OS);
   OS << ProfileNamesData;
   // Coverage mapping data is expected to have an alignment of 8.
-  for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad)
+  for (unsigned Pad = offsetToAlignment(OS.tell(), llvm::Align(8)); Pad; --Pad)
 OS.write(uint8_t(0));
   OS << CoverageMappingData;
 
Index: llvm/tools/dsymutil/DwarfStreamer.cpp
===
--- llvm/tools/dsymutil/DwarfStreamer.cpp
+++ llvm/tools/dsymutil/DwarfStreamer.cpp
@@ -339,7 +339,7 @@
 sizeof(int8_t);   // Segment Size (in bytes)
 
 unsigned TupleSize = AddressSize * 2;
-unsigned Padding = OffsetToAlignment(HeaderSize, TupleSize);
+unsigned Padding = offsetToAlignment(HeaderSize, llvm::Align(TupleSize));
 
 Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Arange length
 Asm->OutStreamer->EmitLabel(BeginLabel);
Index: llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
===
--- llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
+++ llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
@@ -88,13 +88,13 @@
   const llvm::Align ParentAlign = MBB.getParent()->getAlignment();
 
   if (Align <= ParentAlign)
-return OffsetToAlignment(Offset, Align.value());
+return offsetToAlignment(Offset, Align);
 
   // The alignment of this MBB is larger than the function's alignment, so we
   // can't tell whether or not it will insert nops. Assume that it will.
   if (FirstImpreciseBlock < 0)
 FirstImpreciseBlock = MBB.getNumber();
-  return Align.value() + OffsetToAlignment(Offset, Align.value());
+  return Align.value() + offsetToAlignment(Offset, Align);
 }
 
 /// We need to be careful about the offset of the first block in the function
Index: llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
===
--- llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
+++ llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
@@ -212,11 +212,11 @@
 // element size),

[PATCH] D67499: [Alignment] Move OffsetToAlignment to Alignment.h

2019-09-12 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 219923.
gchatelet marked an inline comment as done.
gchatelet added a comment.

- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67499/new/

https://reviews.llvm.org/D67499

Files:
  clang/lib/AST/DeclBase.cpp
  llvm/include/llvm/Support/Alignment.h
  llvm/include/llvm/Support/MathExtras.h
  llvm/include/llvm/Support/OnDiskHashTable.h
  llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
  llvm/lib/CodeGen/BranchRelaxation.cpp
  llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
  llvm/lib/MC/ELFObjectWriter.cpp
  llvm/lib/MC/MCAssembler.cpp
  llvm/lib/MC/MachObjectWriter.cpp
  llvm/lib/Object/ArchiveWriter.cpp
  llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
  llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
  llvm/lib/Target/Mips/MipsConstantIslandPass.cpp
  llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
  llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
  llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
  llvm/tools/dsymutil/DwarfStreamer.cpp
  llvm/tools/llvm-cov/TestingSupport.cpp
  llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp

Index: llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
===
--- llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
+++ llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
@@ -7,6 +7,7 @@
 //===--===//
 
 #include "MachOLayoutBuilder.h"
+#include "llvm/Support/Alignment.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -145,7 +146,7 @@
   Sec.Offset = 0;
 } else {
   uint64_t PaddingSize =
-  OffsetToAlignment(SegFileSize, 1ull << Sec.Align);
+  offsetToAlignment(SegFileSize, llvm::Align(1ull << Sec.Align));
   Sec.Offset = SegOffset + SegFileSize + PaddingSize;
   Sec.Size = Sec.Content.size();
   SegFileSize += PaddingSize + Sec.Size;
Index: llvm/tools/llvm-cov/TestingSupport.cpp
===
--- llvm/tools/llvm-cov/TestingSupport.cpp
+++ llvm/tools/llvm-cov/TestingSupport.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Alignment.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/raw_ostream.h"
@@ -99,7 +100,7 @@
   encodeULEB128(ProfileNamesAddress, OS);
   OS << ProfileNamesData;
   // Coverage mapping data is expected to have an alignment of 8.
-  for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad)
+  for (unsigned Pad = offsetToAlignment(OS.tell(), llvm::Align(8)); Pad; --Pad)
 OS.write(uint8_t(0));
   OS << CoverageMappingData;
 
Index: llvm/tools/dsymutil/DwarfStreamer.cpp
===
--- llvm/tools/dsymutil/DwarfStreamer.cpp
+++ llvm/tools/dsymutil/DwarfStreamer.cpp
@@ -339,7 +339,7 @@
 sizeof(int8_t);   // Segment Size (in bytes)
 
 unsigned TupleSize = AddressSize * 2;
-unsigned Padding = OffsetToAlignment(HeaderSize, TupleSize);
+unsigned Padding = offsetToAlignment(HeaderSize, llvm::Align(TupleSize));
 
 Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Arange length
 Asm->OutStreamer->EmitLabel(BeginLabel);
Index: llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
===
--- llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
+++ llvm/lib/Target/PowerPC/PPCBranchSelector.cpp
@@ -88,13 +88,13 @@
   const llvm::Align ParentAlign = MBB.getParent()->getAlignment();
 
   if (Align <= ParentAlign)
-return OffsetToAlignment(Offset, Align.value());
+return offsetToAlignment(Offset, Align);
 
   // The alignment of this MBB is larger than the function's alignment, so we
   // can't tell whether or not it will insert nops. Assume that it will.
   if (FirstImpreciseBlock < 0)
 FirstImpreciseBlock = MBB.getNumber();
-  return Align.value() + OffsetToAlignment(Offset, Align.value());
+  return Align.value() + offsetToAlignment(Offset, Align);
 }
 
 /// We need to be careful about the offset of the first block in the function
Index: llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
===
--- llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
+++ llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
@@ -212,11 +212,9 @@
 // element size), otherwise it is a 16-bit signed immediate.
 unsigned OffsetBitSize =
 getLoadStoreOffsetSizeInBits(MI.getOpcode(), MI.getOperand(OpNo - 1));
-unsigned OffsetAlign = getLoadStoreOffsetAlign(MI.getOpcode());
-
+const llvm::Align OffsetAlign(getLoadStoreOffsetAlign(MI.getOpcode()));
 if (OffsetBitSize < 16 && isInt<16>(Offset) &&
-(!isIntN(OffsetBitSize, Offset) ||
- OffsetToAlignment(Offset, Offs

[PATCH] D67499: [Alignment] Move OffsetToAlignment to Alignment.h

2019-09-12 Thread Guillaume Chatelet via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL371742: [Alignment] Move OffsetToAlignment to Alignment.h 
(authored by gchatelet, committed by ).
Herald added a subscriber: kristina.

Changed prior to commit:
  https://reviews.llvm.org/D67499?vs=219923&id=219925#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67499/new/

https://reviews.llvm.org/D67499

Files:
  cfe/trunk/lib/AST/DeclBase.cpp
  llvm/trunk/include/llvm/Support/Alignment.h
  llvm/trunk/include/llvm/Support/MathExtras.h
  llvm/trunk/include/llvm/Support/OnDiskHashTable.h
  llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
  llvm/trunk/lib/CodeGen/BranchRelaxation.cpp
  llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
  llvm/trunk/lib/MC/ELFObjectWriter.cpp
  llvm/trunk/lib/MC/MCAssembler.cpp
  llvm/trunk/lib/MC/MachObjectWriter.cpp
  llvm/trunk/lib/Object/ArchiveWriter.cpp
  llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
  llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
  llvm/trunk/lib/Target/Mips/MipsConstantIslandPass.cpp
  llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
  llvm/trunk/lib/Target/Mips/MipsSERegisterInfo.cpp
  llvm/trunk/lib/Target/PowerPC/PPCBranchSelector.cpp
  llvm/trunk/tools/dsymutil/DwarfStreamer.cpp
  llvm/trunk/tools/llvm-cov/TestingSupport.cpp
  llvm/trunk/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp

Index: llvm/trunk/include/llvm/Support/MathExtras.h
===
--- llvm/trunk/include/llvm/Support/MathExtras.h
+++ llvm/trunk/include/llvm/Support/MathExtras.h
@@ -712,13 +712,6 @@
   return (Value - Skew) / Align * Align + Skew;
 }
 
-/// Returns the offset to the next integer (mod 2**64) that is greater than
-/// or equal to \p Value and is a multiple of \p Align. \p Align must be
-/// non-zero.
-inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
-  return alignTo(Value, Align) - Value;
-}
-
 /// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
 /// Requires 0 < B <= 32.
 template  constexpr inline int32_t SignExtend32(uint32_t X) {
Index: llvm/trunk/include/llvm/Support/Alignment.h
===
--- llvm/trunk/include/llvm/Support/Alignment.h
+++ llvm/trunk/include/llvm/Support/Alignment.h
@@ -133,6 +133,12 @@
   return A ? alignTo(Size, A.getValue()) : Size;
 }
 
+/// Returns the offset to the next integer (mod 2**64) that is greater than
+/// or equal to \p Value and is a multiple of \p Align.
+inline uint64_t offsetToAlignment(uint64_t Value, llvm::Align Align) {
+  return alignTo(Value, Align) - Value;
+}
+
 /// Returns the log2 of the alignment.
 inline unsigned Log2(Align A) { return A.ShiftValue; }
 
Index: llvm/trunk/include/llvm/Support/OnDiskHashTable.h
===
--- llvm/trunk/include/llvm/Support/OnDiskHashTable.h
+++ llvm/trunk/include/llvm/Support/OnDiskHashTable.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_SUPPORT_ONDISKHASHTABLE_H
 #define LLVM_SUPPORT_ONDISKHASHTABLE_H
 
+#include "llvm/Support/Alignment.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/EndianStream.h"
@@ -207,7 +208,8 @@
 
 // Pad with zeros so that we can start the hashtable at an aligned address.
 offset_type TableOff = Out.tell();
-uint64_t N = llvm::OffsetToAlignment(TableOff, alignof(offset_type));
+uint64_t N =
+llvm::offsetToAlignment(TableOff, llvm::Align(alignof(offset_type)));
 TableOff += N;
 while (N--)
   LE.write(0);
Index: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
===
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -17,6 +17,7 @@
 #include "RuntimeDyldMachO.h"
 #include "llvm/Object/COFF.h"
 #include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Support/Alignment.h"
 #include "llvm/Support/MSVCErrorWorkarounds.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MathExtras.h"
@@ -737,7 +738,8 @@
   return NameOrErr.takeError();
 if (Align) {
   // This symbol has an alignment requirement.
-  uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align);
+  uint64_t AlignOffset =
+  offsetToAlignment((uint64_t)Addr, llvm::Align(Align));
   Addr += AlignOffset;
   Offset += AlignOffset;
 }
Index: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
===
--- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -1016,14 +1016,14 @@
   BBInfoVector &BBInfo = BBUtils->getBBInfo();
   unsigned CPELogAlign = getCPELogAlign(U.CPEMI);
   unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset(CPELogAlign);
-  

[PATCH] D68028: [clang] Add no_builtin attribute

2019-09-25 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
gchatelet added reviewers: tejohnson, courbet, theraven, t.p.northover, 
jdoerfert.
Herald added subscribers: cfe-commits, mgrang.
Herald added a project: clang.

This is a follow up on https://reviews.llvm.org/D61634
This patch is simpler and only adds the no_builtin attribute.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68028

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/no-builtin.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test

Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -74,6 +74,7 @@
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
+// CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
 // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
 // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable)
Index: clang/test/CodeGen/no-builtin.c
===
--- /dev/null
+++ clang/test/CodeGen/no-builtin.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @foo_no_mempcy() #0
+void foo_no_mempcy() __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_builtins() #1
+void foo_no_builtins() __attribute__((no_builtin)) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_memset() #2
+void foo_no_mempcy_memset() __attribute__((no_builtin("memset", "memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs() #2
+void separate_attrs() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @wildcard_wins() #1
+void wildcard_wins() __attribute__((no_builtin("memset"))) __attribute__((no_builtin)) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
+// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
+// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1068,6 +1068,42 @@
   S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast(D)));
 }
 
+static void handleNoBuiltin(Sema &S, Decl *D, const ParsedAttr &AL) {
+  const StringRef Wildcard = "*";
+  llvm::SmallSetVector FunctionNames;
+
+  // Insert previous NoBuiltin attributes.
+  if (D->hasAttr())
+for (StringRef FunctionName : D->getAttr()->functionNames())
+  FunctionNames.insert(FunctionName);
+
+  if (AL.getNumArgs() == 0)
+FunctionNames.insert(Wildcard);
+  else
+for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
+  StringRef FunctionName;
+  SourceLocation LiteralLoc;
+  if (!S.checkStringLiteralArgumentAttr(AL, I, FunctionName, &LiteralLoc))
+return;
+  FunctionNames.insert(FunctionName);
+}
+
+  // Wildcard is a super set of all builtins, we keep only this one.
+  if (FunctionNames.count(Wildcard) > 0) {
+FunctionNames.clear();
+FunctionNames.insert(Wildcard);
+  }
+
+  auto UniqueFunctionNames = FunctionNames.takeVector();
+  llvm::sort(UniqueFunctionNames);
+
+  if (D->hasAttr())
+D->dropAttr();
+
+  D->addAttr(::new (S.Context) NoBuiltinAttr(
+  S.Context, AL, UniqueFunctionNames.data(), UniqueFunctionNames.size()));
+}
+
 static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   if (D->hasAttr()) {
 S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
@@ -6573,6 +6609,9 @@
   case ParsedAttr::AT_DiagnoseIf:
 handleDiagnoseIfAttr(S, D, AL);
 break;
+  case ParsedAttr::AT_NoBuiltin:
+handleNoBuiltin(S, D, AL);
+break;
   case ParsedAttr::AT_ExtVectorType:
 handleExtVectorTypeAttr(S, D, AL);
 break;
Index: clang/lib/CodeGen/CGCall.cpp
===
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -1849,6 +1849,22 @@
   FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
 if (TargetDecl->hasAttr())
   FuncAttrs.addAttribute(llvm::Attribute::Convergent);
+if (const auto *Attr = TargetDecl->getAttr()) {
+  const auto HasWildcard = llvm::is_contained(Attr->functionNames(), "*");
+  assert(!HasWildcard ||
+ Attr->functionN

[PATCH] D61634: [clang/llvm] Allow efficient implementation of libc's memory functions in C/C++

2019-09-25 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D61634#1679331 , @tejohnson wrote:

> In D61634#1635595 , @tejohnson wrote:
>
> > I had some time to work on this finally late last week. I decided the most 
> > straightforward thing was to implement the necessary interface changes to 
> > the TLI analysis to make it require a Function (without any changes yet to 
> > how that analysis operates). See D66428  
> > that I just mailed for review. That takes care of the most widespread 
> > changes needed for this migration, and afterwards we can change the 
> > analysis to look at the function attributes and make a truly per-function 
> > TLI.
>
>
> D66428  went in a few weeks ago at r371284, 
> and I just mailed the follow on patch D67923 
>  which will adds the support into the TLI 
> analysis to use the Function to override the available builtins (with some of 
> the code stubbed out since we don't yet have those per-Function attributes 
> finalized).
>
> @gchatelet where are you at on finalizing this patch? Also, I mentioned this 
> offline but to follow up here: I think we will want an attribute to represent 
> -fno-builtins (so that it doesn't need to be expanded out into the full list 
> of individual no-builtin-{func} attributes, which would be both more verbose 
> and less efficient, as well as being less backward compatible when new 
> builtin funcs are added).


I'll break this patch in several pieces. The first one is to add the 
`no_builtin` attribute, see https://reviews.llvm.org/D61634.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61634/new/

https://reviews.llvm.org/D61634



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68028: [clang] Add no_builtin attribute

2019-09-26 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 221924.
gchatelet marked 11 inline comments as done.
gchatelet added a comment.

- Address aaron ballman comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/no-builtin.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/no-builtin.c

Index: clang/test/Sema/no-builtin.c
===
--- /dev/null
+++ clang/test/Sema/no-builtin.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -verify %s
+
+void foo() __attribute__((no_builtin)) {}   // expected-error {{'no_builtin' attribute takes at least 1 argument}}
+void bar() __attribute__((no_builtin())) {} // expected-error {{'no_builtin' attribute takes at least 1 argument}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -74,6 +74,7 @@
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
+// CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
 // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
 // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable)
Index: clang/test/CodeGen/no-builtin.c
===
--- /dev/null
+++ clang/test/CodeGen/no-builtin.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @foo_no_mempcy() #0
+void foo_no_mempcy() __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_builtins() #1
+void foo_no_builtins() __attribute__((no_builtin("*"))) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_memset() #2
+void foo_no_mempcy_memset() __attribute__((no_builtin("memset", "memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs() #2
+void separate_attrs() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @wildcard_wins() #1
+void wildcard_wins() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("*"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
+// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
+// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1068,6 +1068,59 @@
   S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast(D)));
 }
 
+NoBuiltinAttr *
+Sema::mergeNoBuiltinAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
+ llvm::ArrayRef FunctionNames) {
+  const StringRef Wildcard = "*";
+  llvm::SmallSetVector FunctionNamesSet;
+
+  // Insert previous NoBuiltin attributes.
+  if (D->hasAttr())
+for (StringRef FunctionName : D->getAttr()->functionNames())
+  FunctionNamesSet.insert(FunctionName);
+  // Insert new NoBuiltin attributes.
+  for (StringRef FunctionName : FunctionNames)
+FunctionNamesSet.insert(FunctionName);
+
+  // Wildcard is a superset of all builtins, we keep only this one.
+  if (FunctionNamesSet.count(Wildcard) > 0) {
+FunctionNamesSet.clear();
+FunctionNamesSet.insert(Wildcard);
+  }
+
+  assert((FunctionNamesSet.count(Wildcard) == 0) ||
+ (FunctionNamesSet.size() == 1) && "Wildcard must be on its own");
+
+  llvm::SmallVector UniqFunctionNames =
+  FunctionNamesSet.takeVector();
+  llvm::sort(UniqFunctionNames);
+
+  if (D->hasAttr())
+D->dropAttr();
+
+  return ::new (S.Context) NoBuiltinAttr(
+  S.Context, CI, UniqFunctionNames.data(), UniqFunctionNames.size());
+}
+
+static void handleNoBuiltin(Sema &S, Decl *D, const ParsedAttr &AL) {
+  if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+return;
+
+  llvm::SmallVector FunctionNames;
+  for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
+StringRef FunctionName;
+SourceLocation LiteralLoc;
+if (!S.checkStringLiteralArgumentAttr(AL, I, FunctionName, &LiteralLoc))
+  return;
+
+// TODO: check that function names are valid for the
+// TargetLibraryInfo.
+FunctionNames.push_back(FunctionName);
+  

[PATCH] D68028: [clang] Add no_builtin attribute

2019-09-26 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

@aaron.ballman thx a lot for the review. I really appreciate it, especially 
because I'm not too familiar with this part of the codebase.




Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1092
+  // Wildcard is a super set of all builtins, we keep only this one.
+  if (FunctionNames.count(Wildcard) > 0) {
+FunctionNames.clear();

aaron.ballman wrote:
> This silently changes the behavior from what the user might expect, which 
> seems bad. For instance, it would be very reasonable for a user to write 
> `[[clang::no_builtin("__builtin_mem*")]]` expecting that to behave as a regex 
> pattern, but instead it silently turns into a "disable all builtins".
> 
> I think it makes sense to diagnose unexpected input like that rather than 
> silently accept it under perhaps unexpected semantics. It may also make sense 
> to support regex patterns in the strings or at least keep the design such 
> that we can add that functionality later without breaking users.
The code looks for a function name that is exactly `*` and not "a function name 
that contains `*`", it would not turn `[[clang::no_builtin("__builtin_mem*")]]` 
into `[[clang::no_builtin("*")]]`.
That said, I fully agree that an error should be returned if the function name 
is not valid.
I'll work on this.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68028: [clang] Add no_builtin attribute

2019-09-26 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 221939.
gchatelet added a comment.

- Checks function name validity and errors when passed 0 argument.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/no-builtin.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/no-builtin.c

Index: clang/test/Sema/no-builtin.c
===
--- /dev/null
+++ clang/test/Sema/no-builtin.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -verify %s
+
+void foo() __attribute__((no_builtin)) {} // expected-error {{'no_builtin' attribute takes at least 1 argument}}
+
+void bar() __attribute__((no_builtin())) {} // expected-error {{'no_builtin' attribute takes at least 1 argument}}
+
+void invalid_builtin() __attribute__((no_builtin("not_a_builtin"))) {} // expected-error {{use of unknown builtin not_a_builtin}}
+
+int __attribute__((no_builtin("*"))) variable; // expected-warning {{'no_builtin' attribute only applies to functions}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -74,6 +74,7 @@
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
+// CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
 // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
 // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable)
Index: clang/test/CodeGen/no-builtin.c
===
--- /dev/null
+++ clang/test/CodeGen/no-builtin.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @foo_no_mempcy() #0
+void foo_no_mempcy() __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_builtins() #1
+void foo_no_builtins() __attribute__((no_builtin("*"))) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_memset() #2
+void foo_no_mempcy_memset() __attribute__((no_builtin("memset", "memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs() #2
+void separate_attrs() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @wildcard_wins() #1
+void wildcard_wins() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("*"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
+// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
+// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1068,6 +1068,62 @@
   S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast(D)));
 }
 
+NoBuiltinAttr *
+Sema::mergeNoBuiltinAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
+ llvm::ArrayRef FunctionNames) {
+  const StringRef Wildcard = "*";
+  llvm::SmallSetVector FunctionNamesSet;
+
+  // Insert previous NoBuiltin attributes.
+  if (D->hasAttr())
+for (StringRef FunctionName : D->getAttr()->functionNames())
+  FunctionNamesSet.insert(FunctionName);
+  // Insert new NoBuiltin attributes.
+  for (StringRef FunctionName : FunctionNames)
+FunctionNamesSet.insert(FunctionName);
+
+  // Wildcard is a superset of all builtins, we keep only this one.
+  if (FunctionNamesSet.count(Wildcard) > 0) {
+FunctionNamesSet.clear();
+FunctionNamesSet.insert(Wildcard);
+  }
+
+  assert((FunctionNamesSet.count(Wildcard) == 0) ||
+ (FunctionNamesSet.size() == 1) && "Wildcard must be on its own");
+
+  llvm::SmallVector UniqFunctionNames =
+  FunctionNamesSet.takeVector();
+  llvm::sort(UniqFunctionNames);
+
+  if (D->hasAttr())
+D->dropAttr();
+
+  return ::new (S.Context) NoBuiltinAttr(
+  S.Context, CI, UniqFunctionNames.data(), UniqFunctionNames.size());
+}
+
+static void handleNoBuiltin(Sema &S, Decl *D, const ParsedAttr &AL) {
+  if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+return;
+
+  llvm::SmallVector FunctionNames;
+  for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
+StringRef FunctionName;
+SourceLoc

[PATCH] D68028: [clang] Add no_builtin attribute

2019-09-27 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

@tejohnson I believe this is the missing part for D67923 
.

I'm unsure if we still need the `BitVector` at all in the `TLI` since it could 
be a simple attribute lookup on the function. Do you see any problematic 
interactions with the inlining phase?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68028: [clang] Add no_builtin attribute

2019-09-27 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 222163.
gchatelet added a comment.

- Update documentation and rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/no-builtin.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/no-builtin.c

Index: clang/test/Sema/no-builtin.c
===
--- /dev/null
+++ clang/test/Sema/no-builtin.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -verify %s
+
+void foo() __attribute__((no_builtin)) {} // expected-error {{'no_builtin' attribute takes at least 1 argument}}
+
+void bar() __attribute__((no_builtin())) {} // expected-error {{'no_builtin' attribute takes at least 1 argument}}
+
+void invalid_builtin() __attribute__((no_builtin("not_a_builtin"))) {} // expected-error {{use of unknown builtin not_a_builtin}}
+
+int __attribute__((no_builtin("*"))) variable; // expected-warning {{'no_builtin' attribute only applies to functions}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -74,6 +74,7 @@
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
+// CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
 // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
 // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable)
Index: clang/test/CodeGen/no-builtin.c
===
--- /dev/null
+++ clang/test/CodeGen/no-builtin.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @foo_no_mempcy() #0
+void foo_no_mempcy() __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_builtins() #1
+void foo_no_builtins() __attribute__((no_builtin("*"))) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_memset() #2
+void foo_no_mempcy_memset() __attribute__((no_builtin("memset", "memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs() #2
+void separate_attrs() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @wildcard_wins() #1
+void wildcard_wins() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("*"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
+// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
+// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1068,6 +1068,62 @@
   S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast(D)));
 }
 
+NoBuiltinAttr *
+Sema::mergeNoBuiltinAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
+ llvm::ArrayRef FunctionNames) {
+  const StringRef Wildcard = "*";
+  llvm::SmallSetVector FunctionNamesSet;
+
+  // Insert previous NoBuiltin attributes.
+  if (D->hasAttr())
+for (StringRef FunctionName : D->getAttr()->functionNames())
+  FunctionNamesSet.insert(FunctionName);
+  // Insert new NoBuiltin attributes.
+  for (StringRef FunctionName : FunctionNames)
+FunctionNamesSet.insert(FunctionName);
+
+  // Wildcard is a superset of all builtins, we keep only this one.
+  if (FunctionNamesSet.count(Wildcard) > 0) {
+FunctionNamesSet.clear();
+FunctionNamesSet.insert(Wildcard);
+  }
+
+  assert((FunctionNamesSet.count(Wildcard) == 0) ||
+ (FunctionNamesSet.size() == 1) && "Wildcard must be on its own");
+
+  llvm::SmallVector UniqFunctionNames =
+  FunctionNamesSet.takeVector();
+  llvm::sort(UniqFunctionNames);
+
+  if (D->hasAttr())
+D->dropAttr();
+
+  return ::new (S.Context) NoBuiltinAttr(
+  S.Context, CI, UniqFunctionNames.data(), UniqFunctionNames.size());
+}
+
+static void handleNoBuiltin(Sema &S, Decl *D, const ParsedAttr &AL) {
+  if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+return;
+
+  llvm::SmallVector FunctionNames;
+  for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
+StringRef FunctionName;
+SourceLocation LiteralLoc;
+if (!S.che

[PATCH] D68141: [Alignment][NFC] Remove AllocaInst::setAlignment(unsigned)

2019-09-27 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
gchatelet added a reviewer: courbet.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya, eraman, 
nhaehnle, jvesely, arsenm, jholewinski.
Herald added projects: clang, LLVM.

This is patch is part of a series to introduce an Alignment type.
See this thread for context: 
http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html
See this patch for the introduction of the type: https://reviews.llvm.org/D64790


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68141

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  llvm/include/llvm/IR/Instructions.h
  llvm/lib/CodeGen/AtomicExpandPass.cpp
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/IR/Core.cpp
  llvm/lib/IR/Instructions.cpp
  llvm/lib/Target/AArch64/AArch64StackTagging.cpp
  llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
  llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp
  llvm/lib/Transforms/Coroutines/CoroFrame.cpp
  llvm/lib/Transforms/IPO/Inliner.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
  llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
  llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
  llvm/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
  llvm/lib/Transforms/Utils/Local.cpp

Index: llvm/lib/Transforms/Utils/Local.cpp
===
--- llvm/lib/Transforms/Utils/Local.cpp
+++ llvm/lib/Transforms/Utils/Local.cpp
@@ -1154,7 +1154,7 @@
 // then don't round up. This avoids dynamic stack realignment.
 if (DL.exceedsNaturalStackAlignment(Align(PrefAlign)))
   return Alignment;
-AI->setAlignment(PrefAlign);
+AI->setAlignment(MaybeAlign(PrefAlign));
 return PrefAlign;
   }
 
Index: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
===
--- llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -895,7 +895,7 @@
   // If the destination wasn't sufficiently aligned then increase its alignment.
   if (!isDestSufficientlyAligned) {
 assert(isa(cpyDest) && "Can only increase alloca alignment!");
-cast(cpyDest)->setAlignment(srcAlign);
+cast(cpyDest)->setAlignment(MaybeAlign(srcAlign));
   }
 
   // Drop any cached information about the call, because we may have changed
Index: llvm/lib/Transforms/Scalar/GVNHoist.cpp
===
--- llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -900,8 +900,8 @@
   ++NumStoresRemoved;
 } else if (auto *ReplacementAlloca = dyn_cast(Repl)) {
   ReplacementAlloca->setAlignment(
-  std::max(ReplacementAlloca->getAlignment(),
-   cast(I)->getAlignment()));
+  MaybeAlign(std::max(ReplacementAlloca->getAlignment(),
+  cast(I)->getAlignment(;
 } else if (isa(Repl)) {
   ++NumCallsRemoved;
 }
Index: llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
===
--- llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -1184,7 +1184,7 @@
 uint64_t Size = getAllocaSizeInBytes(*AI);
 uint64_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
 AI->setAlignment(
-std::max(AI->getAlignment(), Mapping.getObjectAlignment()));
+MaybeAlign(std::max(AI->getAlignment(), Mapping.getObjectAlignment(;
 if (Size != AlignedSize) {
   Type *AllocatedType = AI->getAllocatedType();
   if (AI->isArrayAllocation()) {
@@ -1197,7 +1197,7 @@
   auto *NewAI = new AllocaInst(
   TypeWithPadding, AI->getType()->getAddressSpace(), nullptr, "", AI);
   NewAI->takeName(AI);
-  NewAI->setAlignment(AI->getAlignment());
+  NewAI->setAlignment(MaybeAlign(AI->getAlignment()));
   NewAI->setUsedWithInAlloca(AI->isUsedWithInAlloca());
   NewAI->setSwiftError(AI->isSwiftError());
   NewAI->copyMetadata(*AI);
Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
===
--- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2906,7 +2906,7 @@
   Ty, nullptr,
   (Arg.hasName() ? Arg.getName() : "Arg" + Twine(Arg.getArgNo())) +
   ".byval");
-  AI->setAlignment(Align);
+  AI->setAlignment(MaybeAlign(Align));
   Arg.replaceAllUsesWith(AI);
 
   uint64_t AllocSize = DL.getTypeAllocSize(Ty);
@@ -2941,7 +2941,7 @@
   }
   assert((ClRealignStack & (ClRealignStack - 1)) == 0);
   size_t FrameAlignment = std::max(L.FrameAlignment, (size_t)

[PATCH] D68142: [Alignment][NFC] Remove LoadInst::setAlignment(unsigned)

2019-09-27 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
gchatelet added a reviewer: courbet.
Herald added subscribers: llvm-commits, cfe-commits, asbirlea, hiraditya.
Herald added a reviewer: jdoerfert.
Herald added projects: clang, LLVM.

This is patch is part of a series to introduce an Alignment type.
See this thread for context: 
http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html
See this patch for the introduction of the type: https://reviews.llvm.org/D64790


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68142

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/Instructions.h
  llvm/lib/CodeGen/AtomicExpandPass.cpp
  llvm/lib/IR/Core.cpp
  llvm/lib/IR/Instructions.cpp
  llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
  llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/lib/Transforms/Scalar/LICM.cpp
  llvm/lib/Transforms/Scalar/SROA.cpp
  llvm/lib/Transforms/Utils/VNCoercion.cpp
  llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Index: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
===
--- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -3951,11 +3951,10 @@
   if (getTreeEntry(PO))
 ExternalUses.push_back(ExternalUser(PO, cast(VecPtr), 0));
 
-  unsigned Alignment = LI->getAlignment();
+  MaybeAlign Alignment = MaybeAlign(LI->getAlignment());
   LI = Builder.CreateLoad(VecTy, VecPtr);
-  if (!Alignment) {
-Alignment = DL->getABITypeAlignment(ScalarLoadTy);
-  }
+  if (!Alignment)
+Alignment = MaybeAlign(DL->getABITypeAlignment(ScalarLoadTy));
   LI->setAlignment(Alignment);
   Value *V = propagateMetadata(LI, E->Scalars);
   if (IsReorder) {
Index: llvm/lib/Transforms/Utils/VNCoercion.cpp
===
--- llvm/lib/Transforms/Utils/VNCoercion.cpp
+++ llvm/lib/Transforms/Utils/VNCoercion.cpp
@@ -431,7 +431,7 @@
 PtrVal = Builder.CreateBitCast(PtrVal, DestPTy);
 LoadInst *NewLoad = Builder.CreateLoad(DestTy, PtrVal);
 NewLoad->takeName(SrcVal);
-NewLoad->setAlignment(SrcVal->getAlignment());
+NewLoad->setAlignment(MaybeAlign(SrcVal->getAlignment()));
 
 LLVM_DEBUG(dbgs() << "GVN WIDENED LOAD: " << *SrcVal << "\n");
 LLVM_DEBUG(dbgs() << "TO: " << *NewLoad << "\n");
Index: llvm/lib/Transforms/Scalar/SROA.cpp
===
--- llvm/lib/Transforms/Scalar/SROA.cpp
+++ llvm/lib/Transforms/Scalar/SROA.cpp
@@ -1270,7 +1270,7 @@
   // matter which one we get and if any differ.
   AAMDNodes AATags;
   SomeLoad->getAAMetadata(AATags);
-  unsigned Align = SomeLoad->getAlignment();
+  MaybeAlign Align = MaybeAlign(SomeLoad->getAlignment());
 
   // Rewrite all loads of the PN to use the new PHI.
   while (!PN.use_empty()) {
@@ -1368,8 +1368,8 @@
 NumLoadsSpeculated += 2;
 
 // Transfer alignment and AA info if present.
-TL->setAlignment(LI->getAlignment());
-FL->setAlignment(LI->getAlignment());
+TL->setAlignment(MaybeAlign(LI->getAlignment()));
+FL->setAlignment(MaybeAlign(LI->getAlignment()));
 
 AAMDNodes Tags;
 LI->getAAMetadata(Tags);
@@ -3118,7 +3118,7 @@
 unsigned LoadAlign = LI->getAlignment();
 if (!LoadAlign)
   LoadAlign = DL.getABITypeAlignment(LI->getType());
-LI->setAlignment(std::min(LoadAlign, getSliceAlign()));
+LI->setAlignment(MaybeAlign(std::min(LoadAlign, getSliceAlign(;
 continue;
   }
   if (StoreInst *SI = dyn_cast(I)) {
Index: llvm/lib/Transforms/Scalar/LICM.cpp
===
--- llvm/lib/Transforms/Scalar/LICM.cpp
+++ llvm/lib/Transforms/Scalar/LICM.cpp
@@ -2109,7 +2109,7 @@
   SomePtr->getName() + ".promoted", Preheader->getTerminator());
   if (SawUnorderedAtomic)
 PreheaderLoad->setOrdering(AtomicOrdering::Unordered);
-  PreheaderLoad->setAlignment(Alignment);
+  PreheaderLoad->setAlignment(MaybeAlign(Alignment));
   PreheaderLoad->setDebugLoc(DL);
   if (AATags)
 PreheaderLoad->setAAMetadata(AATags);
Index: llvm/lib/Transforms/Scalar/GVNHoist.cpp
===
--- llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -889,9 +889,8 @@
 
   void updateAlignment(Instruction *I, Instruction *Repl) {
 if (auto *ReplacementLoad = dyn_cast(Repl)) {
-  ReplacementLoad->setAlignment(
-  std::min(ReplacementLoad->getAlignment(),
-  

[PATCH] D68141: [Alignment][NFC] Remove AllocaInst::setAlignment(unsigned)

2019-09-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 222372.
gchatelet added a comment.

- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68141/new/

https://reviews.llvm.org/D68141

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  llvm/include/llvm/IR/Instructions.h
  llvm/lib/CodeGen/AtomicExpandPass.cpp
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/IR/Core.cpp
  llvm/lib/IR/Instructions.cpp
  llvm/lib/Target/AArch64/AArch64StackTagging.cpp
  llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
  llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp
  llvm/lib/Transforms/Coroutines/CoroFrame.cpp
  llvm/lib/Transforms/IPO/Inliner.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
  llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
  llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
  llvm/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
  llvm/lib/Transforms/Utils/Local.cpp

Index: llvm/lib/Transforms/Utils/Local.cpp
===
--- llvm/lib/Transforms/Utils/Local.cpp
+++ llvm/lib/Transforms/Utils/Local.cpp
@@ -1154,7 +1154,7 @@
 // then don't round up. This avoids dynamic stack realignment.
 if (DL.exceedsNaturalStackAlignment(Align(PrefAlign)))
   return Alignment;
-AI->setAlignment(PrefAlign);
+AI->setAlignment(MaybeAlign(PrefAlign));
 return PrefAlign;
   }
 
Index: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
===
--- llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -895,7 +895,7 @@
   // If the destination wasn't sufficiently aligned then increase its alignment.
   if (!isDestSufficientlyAligned) {
 assert(isa(cpyDest) && "Can only increase alloca alignment!");
-cast(cpyDest)->setAlignment(srcAlign);
+cast(cpyDest)->setAlignment(MaybeAlign(srcAlign));
   }
 
   // Drop any cached information about the call, because we may have changed
Index: llvm/lib/Transforms/Scalar/GVNHoist.cpp
===
--- llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -900,8 +900,8 @@
   ++NumStoresRemoved;
 } else if (auto *ReplacementAlloca = dyn_cast(Repl)) {
   ReplacementAlloca->setAlignment(
-  std::max(ReplacementAlloca->getAlignment(),
-   cast(I)->getAlignment()));
+  MaybeAlign(std::max(ReplacementAlloca->getAlignment(),
+  cast(I)->getAlignment(;
 } else if (isa(Repl)) {
   ++NumCallsRemoved;
 }
Index: llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
===
--- llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -1184,7 +1184,7 @@
 uint64_t Size = getAllocaSizeInBytes(*AI);
 uint64_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
 AI->setAlignment(
-std::max(AI->getAlignment(), Mapping.getObjectAlignment()));
+MaybeAlign(std::max(AI->getAlignment(), Mapping.getObjectAlignment(;
 if (Size != AlignedSize) {
   Type *AllocatedType = AI->getAllocatedType();
   if (AI->isArrayAllocation()) {
@@ -1197,7 +1197,7 @@
   auto *NewAI = new AllocaInst(
   TypeWithPadding, AI->getType()->getAddressSpace(), nullptr, "", AI);
   NewAI->takeName(AI);
-  NewAI->setAlignment(AI->getAlignment());
+  NewAI->setAlignment(MaybeAlign(AI->getAlignment()));
   NewAI->setUsedWithInAlloca(AI->isUsedWithInAlloca());
   NewAI->setSwiftError(AI->isSwiftError());
   NewAI->copyMetadata(*AI);
Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
===
--- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2899,18 +2899,19 @@
   for (Argument &Arg : F.args()) {
 if (Arg.hasByValAttr()) {
   Type *Ty = Arg.getType()->getPointerElementType();
-  unsigned Align = Arg.getParamAlignment();
-  if (Align == 0) Align = DL.getABITypeAlignment(Ty);
+  unsigned Alignment = Arg.getParamAlignment();
+  if (Alignment == 0)
+Alignment = DL.getABITypeAlignment(Ty);
 
   AllocaInst *AI = IRB.CreateAlloca(
   Ty, nullptr,
   (Arg.hasName() ? Arg.getName() : "Arg" + Twine(Arg.getArgNo())) +
   ".byval");
-  AI->setAlignment(Align);
+  AI->setAlignment(Align(Alignment));
   Arg.replaceAllUsesWith(AI);
 
   uint64_t AllocSize = DL.getTypeAllocSize(Ty);
-  IRB.CreateMemCpy(AI, Align, &Ar

[PATCH] D68142: [Alignment][NFC] Remove LoadInst::setAlignment(unsigned)

2019-09-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 222380.
gchatelet marked an inline comment as done.
gchatelet added a comment.

- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68142/new/

https://reviews.llvm.org/D68142

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/Instructions.h
  llvm/lib/CodeGen/AtomicExpandPass.cpp
  llvm/lib/IR/Core.cpp
  llvm/lib/IR/Instructions.cpp
  llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
  llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/lib/Transforms/Scalar/LICM.cpp
  llvm/lib/Transforms/Scalar/SROA.cpp
  llvm/lib/Transforms/Utils/VNCoercion.cpp
  llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Index: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
===
--- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -3951,11 +3951,10 @@
   if (getTreeEntry(PO))
 ExternalUses.push_back(ExternalUser(PO, cast(VecPtr), 0));
 
-  unsigned Alignment = LI->getAlignment();
+  MaybeAlign Alignment = MaybeAlign(LI->getAlignment());
   LI = Builder.CreateLoad(VecTy, VecPtr);
-  if (!Alignment) {
-Alignment = DL->getABITypeAlignment(ScalarLoadTy);
-  }
+  if (!Alignment)
+Alignment = MaybeAlign(DL->getABITypeAlignment(ScalarLoadTy));
   LI->setAlignment(Alignment);
   Value *V = propagateMetadata(LI, E->Scalars);
   if (IsReorder) {
Index: llvm/lib/Transforms/Utils/VNCoercion.cpp
===
--- llvm/lib/Transforms/Utils/VNCoercion.cpp
+++ llvm/lib/Transforms/Utils/VNCoercion.cpp
@@ -431,7 +431,7 @@
 PtrVal = Builder.CreateBitCast(PtrVal, DestPTy);
 LoadInst *NewLoad = Builder.CreateLoad(DestTy, PtrVal);
 NewLoad->takeName(SrcVal);
-NewLoad->setAlignment(SrcVal->getAlignment());
+NewLoad->setAlignment(MaybeAlign(SrcVal->getAlignment()));
 
 LLVM_DEBUG(dbgs() << "GVN WIDENED LOAD: " << *SrcVal << "\n");
 LLVM_DEBUG(dbgs() << "TO: " << *NewLoad << "\n");
Index: llvm/lib/Transforms/Scalar/SROA.cpp
===
--- llvm/lib/Transforms/Scalar/SROA.cpp
+++ llvm/lib/Transforms/Scalar/SROA.cpp
@@ -1270,7 +1270,7 @@
   // matter which one we get and if any differ.
   AAMDNodes AATags;
   SomeLoad->getAAMetadata(AATags);
-  unsigned Align = SomeLoad->getAlignment();
+  const MaybeAlign Align = MaybeAlign(SomeLoad->getAlignment());
 
   // Rewrite all loads of the PN to use the new PHI.
   while (!PN.use_empty()) {
@@ -1368,8 +1368,8 @@
 NumLoadsSpeculated += 2;
 
 // Transfer alignment and AA info if present.
-TL->setAlignment(LI->getAlignment());
-FL->setAlignment(LI->getAlignment());
+TL->setAlignment(MaybeAlign(LI->getAlignment()));
+FL->setAlignment(MaybeAlign(LI->getAlignment()));
 
 AAMDNodes Tags;
 LI->getAAMetadata(Tags);
@@ -3118,7 +3118,7 @@
 unsigned LoadAlign = LI->getAlignment();
 if (!LoadAlign)
   LoadAlign = DL.getABITypeAlignment(LI->getType());
-LI->setAlignment(std::min(LoadAlign, getSliceAlign()));
+LI->setAlignment(MaybeAlign(std::min(LoadAlign, getSliceAlign(;
 continue;
   }
   if (StoreInst *SI = dyn_cast(I)) {
Index: llvm/lib/Transforms/Scalar/LICM.cpp
===
--- llvm/lib/Transforms/Scalar/LICM.cpp
+++ llvm/lib/Transforms/Scalar/LICM.cpp
@@ -2109,7 +2109,7 @@
   SomePtr->getName() + ".promoted", Preheader->getTerminator());
   if (SawUnorderedAtomic)
 PreheaderLoad->setOrdering(AtomicOrdering::Unordered);
-  PreheaderLoad->setAlignment(Alignment);
+  PreheaderLoad->setAlignment(MaybeAlign(Alignment));
   PreheaderLoad->setDebugLoc(DL);
   if (AATags)
 PreheaderLoad->setAAMetadata(AATags);
Index: llvm/lib/Transforms/Scalar/GVNHoist.cpp
===
--- llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -889,9 +889,8 @@
 
   void updateAlignment(Instruction *I, Instruction *Repl) {
 if (auto *ReplacementLoad = dyn_cast(Repl)) {
-  ReplacementLoad->setAlignment(
-  std::min(ReplacementLoad->getAlignment(),
-   cast(I)->getAlignment()));
+  ReplacementLoad->setAlignment(MaybeAlign(std::min(
+  ReplacementLoad->getAlignment(), cast(I)->getAlignment(;
   ++NumLoadsRemoved;
 } else if (auto *ReplacementStore = dyn_cast(Repl)) {

[PATCH] D68142: [Alignment][NFC] Remove LoadInst::setAlignment(unsigned)

2019-09-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL373195: [Alignment][NFC] Remove 
LoadInst::setAlignment(unsigned) (authored by gchatelet, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D68142?vs=222380&id=222381#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68142/new/

https://reviews.llvm.org/D68142

Files:
  cfe/trunk/lib/CodeGen/CGCleanup.cpp
  llvm/trunk/include/llvm/IR/IRBuilder.h
  llvm/trunk/include/llvm/IR/Instructions.h
  llvm/trunk/lib/CodeGen/AtomicExpandPass.cpp
  llvm/trunk/lib/IR/Core.cpp
  llvm/trunk/lib/IR/Instructions.cpp
  llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
  llvm/trunk/lib/Transforms/IPO/Attributor.cpp
  llvm/trunk/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
  llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
  llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/trunk/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/trunk/lib/Transforms/Scalar/LICM.cpp
  llvm/trunk/lib/Transforms/Scalar/SROA.cpp
  llvm/trunk/lib/Transforms/Utils/VNCoercion.cpp
  llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp

Index: llvm/trunk/include/llvm/IR/Instructions.h
===
--- llvm/trunk/include/llvm/IR/Instructions.h
+++ llvm/trunk/include/llvm/IR/Instructions.h
@@ -248,8 +248,6 @@
 return 0;
   }
 
-  // FIXME: Remove once migration to Align is over.
-  void setAlignment(unsigned Align);
   void setAlignment(MaybeAlign Align);
 
   /// Returns the ordering constraint of this load instruction.
Index: llvm/trunk/include/llvm/IR/IRBuilder.h
===
--- llvm/trunk/include/llvm/IR/IRBuilder.h
+++ llvm/trunk/include/llvm/IR/IRBuilder.h
@@ -1612,19 +1612,19 @@
   LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align,
   const char *Name) {
 LoadInst *LI = CreateLoad(Ty, Ptr, Name);
-LI->setAlignment(Align);
+LI->setAlignment(MaybeAlign(Align));
 return LI;
   }
   LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align,
   const Twine &Name = "") {
 LoadInst *LI = CreateLoad(Ty, Ptr, Name);
-LI->setAlignment(Align);
+LI->setAlignment(MaybeAlign(Align));
 return LI;
   }
   LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align,
   bool isVolatile, const Twine &Name = "") {
 LoadInst *LI = CreateLoad(Ty, Ptr, isVolatile, Name);
-LI->setAlignment(Align);
+LI->setAlignment(MaybeAlign(Align));
 return LI;
   }
 
Index: llvm/trunk/lib/IR/Core.cpp
===
--- llvm/trunk/lib/IR/Core.cpp
+++ llvm/trunk/lib/IR/Core.cpp
@@ -2012,7 +2012,7 @@
   else if (AllocaInst *AI = dyn_cast(P))
 AI->setAlignment(Bytes);
   else if (LoadInst *LI = dyn_cast(P))
-LI->setAlignment(Bytes);
+LI->setAlignment(MaybeAlign(Bytes));
   else if (StoreInst *SI = dyn_cast(P))
 SI->setAlignment(Bytes);
   else
Index: llvm/trunk/lib/IR/Instructions.cpp
===
--- llvm/trunk/lib/IR/Instructions.cpp
+++ llvm/trunk/lib/IR/Instructions.cpp
@@ -1321,7 +1321,7 @@
 : UnaryInstruction(Ty, Load, Ptr, InsertBef) {
   assert(Ty == cast(Ptr->getType())->getElementType());
   setVolatile(isVolatile);
-  setAlignment(Align);
+  setAlignment(MaybeAlign(Align));
   setAtomic(Order, SSID);
   AssertOK();
   setName(Name);
@@ -1333,16 +1333,12 @@
 : UnaryInstruction(Ty, Load, Ptr, InsertAE) {
   assert(Ty == cast(Ptr->getType())->getElementType());
   setVolatile(isVolatile);
-  setAlignment(Align);
+  setAlignment(MaybeAlign(Align));
   setAtomic(Order, SSID);
   AssertOK();
   setName(Name);
 }
 
-void LoadInst::setAlignment(unsigned Align) {
-  setAlignment(llvm::MaybeAlign(Align));
-}
-
 void LoadInst::setAlignment(MaybeAlign Align) {
   assert((!Align || *Align <= MaximumAlignment) &&
  "Alignment is greater than MaximumAlignment!");
Index: llvm/trunk/lib/CodeGen/AtomicExpandPass.cpp
===
--- llvm/trunk/lib/CodeGen/AtomicExpandPass.cpp
+++ llvm/trunk/lib/CodeGen/AtomicExpandPass.cpp
@@ -382,7 +382,7 @@
   Value *NewAddr = Builder.CreateBitCast(Addr, PT);
 
   auto *NewLI = Builder.CreateLoad(NewTy, NewAddr);
-  NewLI->setAlignment(LI->getAlignment());
+  NewLI->setAlignment(MaybeAlign(LI->getAlignment()));
   NewLI->setVolatile(LI->isVolatile());
   NewLI->setAtomic(LI->getOrdering(), LI->getSyncScopeID());
   LLVM_DEBUG(dbgs() << "Replaced " << *LI << " with " << *NewLI << "\n");
@@ -1376,7 +1376,7 @@
   Builder.SetInsertPoint(BB);
   LoadInst *InitLoaded = Builder.CreateLoad(ResultTy, Ad

[PATCH] D68142: [Alignment][NFC] Remove LoadInst::setAlignment(unsigned)

2019-09-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

This patch broke polly, I'm working on a fix.


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68142/new/

https://reviews.llvm.org/D68142



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68142: [Alignment][NFC] Remove LoadInst::setAlignment(unsigned)

2019-09-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

In D68142#1687693 , @gchatelet wrote:

> This patch broke polly, I'm working on a fix.


https://reviews.llvm.org/rL373199


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68142/new/

https://reviews.llvm.org/D68142



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68141: [Alignment][NFC] Remove AllocaInst::setAlignment(unsigned)

2019-09-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 222400.
gchatelet marked an inline comment as done.
gchatelet added a comment.
Herald added a reviewer: bollu.

- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68141/new/

https://reviews.llvm.org/D68141

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  llvm/include/llvm/IR/Instructions.h
  llvm/lib/CodeGen/AtomicExpandPass.cpp
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/IR/Core.cpp
  llvm/lib/IR/Instructions.cpp
  llvm/lib/Target/AArch64/AArch64StackTagging.cpp
  llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
  llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp
  llvm/lib/Transforms/Coroutines/CoroFrame.cpp
  llvm/lib/Transforms/IPO/Inliner.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
  llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
  llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
  llvm/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
  llvm/lib/Transforms/Utils/Local.cpp
  polly/lib/CodeGen/IslNodeBuilder.cpp

Index: polly/lib/CodeGen/IslNodeBuilder.cpp
===
--- polly/lib/CodeGen/IslNodeBuilder.cpp
+++ polly/lib/CodeGen/IslNodeBuilder.cpp
@@ -1497,7 +1497,8 @@
 
   auto *CreatedArray = new AllocaInst(NewArrayType, DL.getAllocaAddrSpace(),
   SAI->getName(), &*InstIt);
-  CreatedArray->setAlignment(PollyTargetFirstLevelCacheLineSize);
+  CreatedArray->setAlignment(
+  MaybeAlign(PollyTargetFirstLevelCacheLineSize));
   SAI->setBasePtr(CreatedArray);
 }
   }
Index: llvm/lib/Transforms/Utils/Local.cpp
===
--- llvm/lib/Transforms/Utils/Local.cpp
+++ llvm/lib/Transforms/Utils/Local.cpp
@@ -1154,7 +1154,7 @@
 // then don't round up. This avoids dynamic stack realignment.
 if (DL.exceedsNaturalStackAlignment(Align(PrefAlign)))
   return Alignment;
-AI->setAlignment(PrefAlign);
+AI->setAlignment(MaybeAlign(PrefAlign));
 return PrefAlign;
   }
 
Index: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
===
--- llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -895,7 +895,7 @@
   // If the destination wasn't sufficiently aligned then increase its alignment.
   if (!isDestSufficientlyAligned) {
 assert(isa(cpyDest) && "Can only increase alloca alignment!");
-cast(cpyDest)->setAlignment(srcAlign);
+cast(cpyDest)->setAlignment(MaybeAlign(srcAlign));
   }
 
   // Drop any cached information about the call, because we may have changed
Index: llvm/lib/Transforms/Scalar/GVNHoist.cpp
===
--- llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -899,8 +899,8 @@
   ++NumStoresRemoved;
 } else if (auto *ReplacementAlloca = dyn_cast(Repl)) {
   ReplacementAlloca->setAlignment(
-  std::max(ReplacementAlloca->getAlignment(),
-   cast(I)->getAlignment()));
+  MaybeAlign(std::max(ReplacementAlloca->getAlignment(),
+  cast(I)->getAlignment(;
 } else if (isa(Repl)) {
   ++NumCallsRemoved;
 }
Index: llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
===
--- llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -1184,7 +1184,7 @@
 uint64_t Size = getAllocaSizeInBytes(*AI);
 uint64_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
 AI->setAlignment(
-std::max(AI->getAlignment(), Mapping.getObjectAlignment()));
+MaybeAlign(std::max(AI->getAlignment(), Mapping.getObjectAlignment(;
 if (Size != AlignedSize) {
   Type *AllocatedType = AI->getAllocatedType();
   if (AI->isArrayAllocation()) {
@@ -1197,7 +1197,7 @@
   auto *NewAI = new AllocaInst(
   TypeWithPadding, AI->getType()->getAddressSpace(), nullptr, "", AI);
   NewAI->takeName(AI);
-  NewAI->setAlignment(AI->getAlignment());
+  NewAI->setAlignment(MaybeAlign(AI->getAlignment()));
   NewAI->setUsedWithInAlloca(AI->isUsedWithInAlloca());
   NewAI->setSwiftError(AI->isSwiftError());
   NewAI->copyMetadata(*AI);
Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
===
--- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2899,18 +2899,19 @@
   for (Argument &Arg : F.args()) {

[PATCH] D68141: [Alignment][NFC] Remove AllocaInst::setAlignment(unsigned)

2019-09-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL373207: [Alignment][NFC] Remove 
AllocaInst::setAlignment(unsigned) (authored by gchatelet, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D68141?vs=222400&id=222409#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68141/new/

https://reviews.llvm.org/D68141

Files:
  cfe/trunk/lib/CodeGen/CGBuiltin.cpp
  cfe/trunk/lib/CodeGen/CGCall.cpp
  cfe/trunk/lib/CodeGen/CGExpr.cpp
  cfe/trunk/lib/CodeGen/TargetInfo.cpp
  llvm/trunk/include/llvm/IR/Instructions.h
  llvm/trunk/lib/CodeGen/AtomicExpandPass.cpp
  llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
  llvm/trunk/lib/IR/Core.cpp
  llvm/trunk/lib/IR/Instructions.cpp
  llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp
  llvm/trunk/lib/Target/AMDGPU/AMDGPULibCalls.cpp
  llvm/trunk/lib/Target/NVPTX/NVPTXLowerArgs.cpp
  llvm/trunk/lib/Transforms/Coroutines/CoroFrame.cpp
  llvm/trunk/lib/Transforms/IPO/Inliner.cpp
  llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
  llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
  llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
  llvm/trunk/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
  llvm/trunk/lib/Transforms/Utils/Local.cpp
  polly/trunk/lib/CodeGen/IslNodeBuilder.cpp

Index: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
===
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp
@@ -2366,7 +2366,7 @@
 .toCharUnitsFromBits(TI.getSuitableAlign())
 .getQuantity();
 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
-AI->setAlignment(SuitableAlignmentInBytes);
+AI->setAlignment(MaybeAlign(SuitableAlignmentInBytes));
 initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes);
 return RValue::get(AI);
   }
@@ -2379,7 +2379,7 @@
 unsigned AlignmentInBytes =
 CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity();
 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
-AI->setAlignment(AlignmentInBytes);
+AI->setAlignment(MaybeAlign(AlignmentInBytes));
 initializeAlloca(*this, AI, Size, AlignmentInBytes);
 return RValue::get(AI);
   }
Index: cfe/trunk/lib/CodeGen/CGExpr.cpp
===
--- cfe/trunk/lib/CodeGen/CGExpr.cpp
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp
@@ -66,7 +66,7 @@
  const Twine &Name,
  llvm::Value *ArraySize) {
   auto Alloca = CreateTempAlloca(Ty, Name, ArraySize);
-  Alloca->setAlignment(Align.getQuantity());
+  Alloca->setAlignment(llvm::MaybeAlign(Align.getQuantity()));
   return Address(Alloca, Align);
 }
 
Index: cfe/trunk/lib/CodeGen/CGCall.cpp
===
--- cfe/trunk/lib/CodeGen/CGCall.cpp
+++ cfe/trunk/lib/CodeGen/CGCall.cpp
@@ -3841,7 +3841,7 @@
   AI = CreateTempAlloca(ArgStruct, "argmem");
 }
 auto Align = CallInfo.getArgStructAlignment();
-AI->setAlignment(Align.getQuantity());
+AI->setAlignment(llvm::MaybeAlign(Align.getQuantity()));
 AI->setUsedWithInAlloca(true);
 assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
 ArgMemory = Address(AI, Align);
Index: cfe/trunk/lib/CodeGen/TargetInfo.cpp
===
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp
@@ -9954,7 +9954,7 @@
   Builder.SetInsertPoint(BB);
   unsigned BlockAlign = CGF.CGM.getDataLayout().getPrefTypeAlignment(BlockTy);
   auto *BlockPtr = Builder.CreateAlloca(BlockTy, nullptr);
-  BlockPtr->setAlignment(BlockAlign);
+  BlockPtr->setAlignment(llvm::MaybeAlign(BlockAlign));
   Builder.CreateAlignedStore(F->arg_begin(), BlockPtr, BlockAlign);
   auto *Cast = Builder.CreatePointerCast(BlockPtr, InvokeFT->getParamType(0));
   llvm::SmallVector Args;
Index: llvm/trunk/include/llvm/IR/Instructions.h
===
--- llvm/trunk/include/llvm/IR/Instructions.h
+++ llvm/trunk/include/llvm/IR/Instructions.h
@@ -114,8 +114,6 @@
   return MA->value();
 return 0;
   }
-  // FIXME: Remove once migration to Align is over.
-  void setAlignment(unsigned Align);
   void setAlignment(MaybeAlign Align);
 
   /// Return true if this alloca is in the entry block of the function and is a
Index: llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp
===
--- llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp
+++ llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp
@@ -62,7 +62,7 @@
 static cl::opt ClScanLimit("st

[PATCH] D68141: [Alignment][NFC] Remove AllocaInst::setAlignment(unsigned)

2019-09-30 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked an inline comment as done.
gchatelet added inline comments.



Comment at: llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp:65
 
-static constexpr unsigned kTagGranuleSize = 16;
+static const Align kTagGranuleSize = Align(16);
 

arichardson wrote:
> Can't the Align ctor be constexpr? Will this result in a `Log2` call at 
> runtime?
The implementation of Log2 is quite complex and depends on the implementation 
of [[ 
https://github.com/llvm/llvm-project/blob/02ada9bd2b41d850876a483bede59715e7550c1e/llvm/include/llvm/Support/MathExtras.h#L127
 | countLeadingZeros ]].
GCC, clang, ICC can compute the value at compile time but there may be some 
compiler that can't.
https://godbolt.org/z/ytwWHn

I could solve this issue by introducing a `LogAlign()` function returning an 
`Align`. This function could be `constexpr`. What do you think? Is it worth the 
additional complexity?


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68141/new/

https://reviews.llvm.org/D68141



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68028: [clang] Add no_builtin attribute

2019-10-01 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked 7 inline comments as done.
gchatelet added a comment.

thx @aaron.ballman , I'm waiting for your reply before uploading the new patch 
(some of my comments won't have the accompanying code update sorry)




Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1072
+NoBuiltinAttr *
+Sema::mergeNoBuiltinAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
+ llvm::ArrayRef FunctionNames) {

aaron.ballman wrote:
> You're missing a call to this function within `mergeDeclAttribute()` in 
> SemaDecl.cpp.
Thx, I rearranged the signature a bit, do you happen to know how 
`mergeDeclAttribute` is tested?



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1078-1079
+  // Insert previous NoBuiltin attributes.
+  if (D->hasAttr())
+for (StringRef FunctionName : D->getAttr()->functionNames())
+  FunctionNamesSet.insert(FunctionName);

aaron.ballman wrote:
> Instead of doing `hasAttr<>` followed by `getAttr<>`, this should be:
> ```
> if (const auto *NBA = D->getAttr()) {
>   for (StringRef FunctionName : NBA->functionNames())
> ...
> }
> ```
> But are you able to use `llvm::copy()` instead of a manual loop?
I had to use a vector instead of a set and //uniquify// by hand.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1086-1089
+  if (FunctionNamesSet.count(Wildcard) > 0) {
+FunctionNamesSet.clear();
+FunctionNamesSet.insert(Wildcard);
+  }

aaron.ballman wrote:
> Rather than walking the entire set like this, would it make more sense to 
> look for the wildcard in the above loop before inserting the name, and set a 
> local variable if found, so that you can do the clear without having to 
> rescan the entire list?
This is is conflict with the `llvm::copy` suggestion above. Which one do you 
prefer?



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1098-1099
+
+  if (D->hasAttr())
+D->dropAttr();
+

aaron.ballman wrote:
> Just making sure I understand the semantics you want: redeclarations do not 
> have to have matching lists of builtins, but instead the definition will use 
> a merged list? e.g.,
> ```
> [[clang::no_builtin("memset")]] void whatever();
> [[clang::no_builtin("memcpy")]] void whatever();
> 
> [[clang::no_builtin("memmove")]] void whatever() {
>  // Will not use memset, memcpy, or memmove builtins.
> }
> ```
> That seems a bit strange, to me. In fact, being able to apply this attribute 
> to a declaration seems a bit like a mistake -- this only impacts the 
> definition of the function, and I can't imagine good things coming from 
> hypothetical code like:
> ```
> [[clang::no_builtin("memset")]] void whatever();
> #include "whatever.h" // Provides a library declaration of whatever() with no 
> restrictions on it
> ```
> WDYT about restricting this attribute to only appear on definitions?
That's a very good point. Thx for noticing.
Indeed I think it only makes sense to have the attribute on the function 
definition.

I've tried to to use `FunctionDecl->hasBody()` during attribute handling in the 
Sema phase but it seems like the `FunctionDecl` is not complete at this point.
All calls to `hasBody()` return `false`, if I repeat the operation in `CGCall` 
then `hasBody` returns `true` and I can see the `CompoundStatement`.

Do you have any recommendations on where to perform the check?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68268: [Alignment][NFC] Remove StoreInst::setAlignment(unsigned)

2019-10-01 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
gchatelet added a reviewer: courbet.
Herald added a reviewer: bollu.
Herald added subscribers: llvm-commits, cfe-commits, asbirlea, hiraditya.
Herald added a reviewer: jdoerfert.
Herald added projects: clang, LLVM.

This is patch is part of a series to introduce an Alignment type.
See this thread for context: 
http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html
See this patch for the introduction of the type: https://reviews.llvm.org/D64790


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68268

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/Instructions.h
  llvm/lib/CodeGen/AtomicExpandPass.cpp
  llvm/lib/IR/Core.cpp
  llvm/lib/IR/Instructions.cpp
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/lib/Transforms/Scalar/LICM.cpp
  llvm/lib/Transforms/Scalar/SROA.cpp
  llvm/lib/Transforms/Utils/SimplifyCFG.cpp
  llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
  polly/lib/CodeGen/BlockGenerators.cpp

Index: polly/lib/CodeGen/BlockGenerators.cpp
===
--- polly/lib/CodeGen/BlockGenerators.cpp
+++ polly/lib/CodeGen/BlockGenerators.cpp
@@ -1209,7 +1209,7 @@
 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
 
 if (!Aligned)
-  Store->setAlignment(8);
+  Store->setAlignment(Align(8));
   } else {
 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
   Value *Scalar = Builder.CreateExtractElement(Vector, Builder.getInt32(i));
Index: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
===
--- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -4024,7 +4024,7 @@
   if (!Alignment)
 Alignment = DL->getABITypeAlignment(SI->getValueOperand()->getType());
 
-  ST->setAlignment(Alignment);
+  ST->setAlignment(Align(Alignment));
   Value *V = propagateMetadata(ST, E->Scalars);
   if (NeedToShuffleReuses) {
 V = Builder.CreateShuffleVector(V, UndefValue::get(VecTy),
Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp
===
--- llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -3087,15 +3087,15 @@
   // store that doesn't execute.
   if (MinAlignment != 0) {
 // Choose the minimum of all non-zero alignments.
-SI->setAlignment(MinAlignment);
+SI->setAlignment(Align(MinAlignment));
   } else if (MaxAlignment != 0) {
 // Choose the minimal alignment between the non-zero alignment and the ABI
 // default alignment for the type of the stored value.
-SI->setAlignment(std::min(MaxAlignment, TypeAlignment));
+SI->setAlignment(Align(std::min(MaxAlignment, TypeAlignment)));
   } else {
 // If both alignments are zero, use ABI default alignment for the type of
 // the stored value.
-SI->setAlignment(TypeAlignment);
+SI->setAlignment(Align(TypeAlignment));
   }
 
   QStore->eraseFromParent();
Index: llvm/lib/Transforms/Scalar/SROA.cpp
===
--- llvm/lib/Transforms/Scalar/SROA.cpp
+++ llvm/lib/Transforms/Scalar/SROA.cpp
@@ -3127,7 +3127,7 @@
   Value *Op = SI->getOperand(0);
   StoreAlign = DL.getABITypeAlignment(Op->getType());
 }
-SI->setAlignment(std::min(StoreAlign, getSliceAlign()));
+SI->setAlignment(MaybeAlign(std::min(StoreAlign, getSliceAlign(;
 continue;
   }
 
Index: llvm/lib/Transforms/Scalar/LICM.cpp
===
--- llvm/lib/Transforms/Scalar/LICM.cpp
+++ llvm/lib/Transforms/Scalar/LICM.cpp
@@ -1791,7 +1791,7 @@
   StoreInst *NewSI = new StoreInst(LiveInValue, Ptr, InsertPos);
   if (UnorderedAtomic)
 NewSI->setOrdering(AtomicOrdering::Unordered);
-  NewSI->setAlignment(Alignment);
+  NewSI->setAlignment(MaybeAlign(Alignment));
   NewSI->setDebugLoc(DL);
   if (AATags)
 NewSI->setAAMetadata(AATags);
Index: llvm/lib/Transforms/Scalar/GVNHoist.cpp
===
--- llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -894,8 +894,8 @@
   ++NumLoadsRemoved;
 } else if (auto *ReplacementStore = dyn_cast(Repl)) {
   ReplacementStore->setAlignment(
-  std::min(ReplacementStore->getAlignment(),
-   cast(I)->getAlignment()));
+  M

[PATCH] D68274: [Alignment][Clang][NFC] Add CharUnits::getAsAlign

2019-10-01 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
gchatelet added a reviewer: courbet.
Herald added subscribers: cfe-commits, jholewinski.
Herald added a project: clang.

This is a prerequisite to removing `llvm::GlobalObject::setAlignment(unsigned)`.
This is patch is part of a series to introduce an Alignment type.
See this thread for context: 
http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html
See this patch for the introduction of the type: https://reviews.llvm.org/D64790


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68274

Files:
  clang/include/clang/AST/CharUnits.h
  clang/lib/CodeGen/CGCUDANV.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/CodeGen/CGExprCXX.cpp
  clang/lib/CodeGen/CGExprConstant.cpp
  clang/lib/CodeGen/CGObjCGNU.cpp
  clang/lib/CodeGen/CGObjCMac.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/ConstantInitBuilder.cpp
  clang/lib/CodeGen/CoverageMappingGen.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp

Index: clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
===
--- clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -279,7 +279,7 @@
 *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, Data,
 "__clang_ast");
 // The on-disk hashtable needs to be aligned.
-ASTSym->setAlignment(8);
+ASTSym->setAlignment(llvm::Align(8));
 
 // Mach-O also needs a segment name.
 if (Triple.isOSBinFormatMachO())
Index: clang/lib/CodeGen/MicrosoftCXXABI.cpp
===
--- clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -2355,7 +2355,7 @@
   /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage,
   /*Initializer=*/nullptr, VarName,
   /*InsertBefore=*/nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
-  GV->setAlignment(Align.getQuantity());
+  GV->setAlignment(Align.getAsAlign());
   return ConstantAddress(GV, Align);
 }
 
@@ -2498,7 +2498,7 @@
  GV->getLinkage(), Zero, GuardName.str());
 GuardVar->setVisibility(GV->getVisibility());
 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
-GuardVar->setAlignment(GuardAlign.getQuantity());
+GuardVar->setAlignment(GuardAlign.getAsAlign());
 if (GuardVar->isWeakForLinker())
   GuardVar->setComdat(
   CGM.getModule().getOrInsertComdat(GuardVar->getName()));
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2194,7 +2194,7 @@
 guard->setVisibility(var->getVisibility());
 // If the variable is thread-local, so is its guard variable.
 guard->setThreadLocalMode(var->getThreadLocalMode());
-guard->setAlignment(guardAlignment.getQuantity());
+guard->setAlignment(guardAlignment.getAsAlign());
 
 // The ABI says: "It is suggested that it be emitted in the same COMDAT
 // group as the associated data object." In practice, this doesn't work for
@@ -2547,7 +2547,7 @@
 Guard->setThreadLocal(true);
 
 CharUnits GuardAlign = CharUnits::One();
-Guard->setAlignment(GuardAlign.getQuantity());
+Guard->setAlignment(GuardAlign.getAsAlign());
 
 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(
 InitFunc, OrderedInits, ConstantAddress(Guard, GuardAlign));
@@ -3479,7 +3479,7 @@
 
   CharUnits Align =
   CGM.getContext().toCharUnitsFromBits(CGM.getTarget().getPointerAlign(0));
-  GV->setAlignment(Align.getQuantity());
+  GV->setAlignment(Align.getAsAlign());
 
   // The Itanium ABI specifies that type_info objects must be globally
   // unique, with one exception: if the type is an incomplete class
Index: clang/lib/CodeGen/CoverageMappingGen.cpp
===
--- clang/lib/CodeGen/CoverageMappingGen.cpp
+++ clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -1442,7 +1442,7 @@
   CovDataVal, llvm::getCoverageMappingVarName());
 
   CovData->setSection(getCoverageSection(CGM));
-  CovData->setAlignment(8);
+  CovData->setAlignment(llvm::Align(8));
 
   // Make sure the data doesn't get deleted.
   CGM.addUsedGlobal(CovData);
Index: clang/lib/CodeGen/ConstantInitBuilder.cpp
===
--- clang/lib/CodeGen/ConstantInitBuilder.cpp
+++ clang/lib/CodeGen/ConstantInitBuilder.cpp
@@ -79,7 +79,7 @@
  /*insert before*/ nullptr,

[PATCH] D68141: [Alignment][NFC] Remove AllocaInst::setAlignment(unsigned)

2019-10-02 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked an inline comment as done.
gchatelet added inline comments.



Comment at: llvm/trunk/lib/Target/AArch64/AArch64StackTagging.cpp:65
 
-static constexpr unsigned kTagGranuleSize = 16;
+static const Align kTagGranuleSize = Align(16);
 

arichardson wrote:
> gchatelet wrote:
> > arichardson wrote:
> > > Can't the Align ctor be constexpr? Will this result in a `Log2` call at 
> > > runtime?
> > The implementation of Log2 is quite complex and depends on the 
> > implementation of [[ 
> > https://github.com/llvm/llvm-project/blob/02ada9bd2b41d850876a483bede59715e7550c1e/llvm/include/llvm/Support/MathExtras.h#L127
> >  | countLeadingZeros ]].
> > GCC, clang, ICC can compute the value at compile time but there may be some 
> > compiler that can't.
> > https://godbolt.org/z/ytwWHn
> > 
> > I could solve this issue by introducing a `LogAlign()` function returning 
> > an `Align`. This function could be `constexpr`. What do you think? Is it 
> > worth the additional complexity?
> Since there won't a global ctor at -O2 or higher it probably doesn't matter.
> 
> I'm not sure if there have been any of these cases yet, but I would think 
> that having a `LogAlign/Align::fromLog()/etc.` might still be useful for some 
> cases where you get the alignment as log2 instead of in bytes?
> This would avoid additional work for the compiler and might be easier to read 
> since you can omit the `1

[PATCH] D68379: FunctionDecl::isThisDeclarationADefinition is useless in ProcessDeclAttribute

2019-10-03 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This is for illustration purposes and not to be submitted


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68379

Files:
  clang/lib/Sema/SemaDeclAttr.cpp


Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1798,12 +1798,12 @@
   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
 return;
 
-  // Aliases should be on declarations, not definitions.
-  const auto *FD = cast(D);
-  if (FD->isThisDeclarationADefinition()) {
-S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
-return;
-  }
+  // // Aliases should be on declarations, not definitions.
+  // const auto *FD = cast(D);
+  // if (FD->isThisDeclarationADefinition()) {
+  //   S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
+  //   return;
+  // }
 
   D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
 }
@@ -1823,10 +1823,10 @@
 
   // Aliases should be on declarations, not definitions.
   if (const auto *FD = dyn_cast(D)) {
-if (FD->isThisDeclarationADefinition()) {
-  S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
-  return;
-}
+// if (FD->isThisDeclarationADefinition()) {
+//   S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
+//   return;
+// }
   } else {
 const auto *VD = cast(D);
 if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
@@ -5628,10 +5628,10 @@
   }
 
   auto *FD = cast(D);
-  if (FD->isThisDeclarationADefinition()) {
-S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
-return;
-  }
+  // if (FD->isThisDeclarationADefinition()) {
+  //   S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+  //   return;
+  // }
 
   StringRef Str;
   SourceLocation ArgLoc;
@@ -5650,10 +5650,10 @@
   }
 
   auto *FD = cast(D);
-  if (FD->isThisDeclarationADefinition()) {
-S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
-return;
-  }
+  // if (FD->isThisDeclarationADefinition()) {
+  //   S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+  //   return;
+  // }
 
   StringRef Str;
   SourceLocation ArgLoc;


Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1798,12 +1798,12 @@
   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
 return;
 
-  // Aliases should be on declarations, not definitions.
-  const auto *FD = cast(D);
-  if (FD->isThisDeclarationADefinition()) {
-S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
-return;
-  }
+  // // Aliases should be on declarations, not definitions.
+  // const auto *FD = cast(D);
+  // if (FD->isThisDeclarationADefinition()) {
+  //   S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
+  //   return;
+  // }
 
   D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
 }
@@ -1823,10 +1823,10 @@
 
   // Aliases should be on declarations, not definitions.
   if (const auto *FD = dyn_cast(D)) {
-if (FD->isThisDeclarationADefinition()) {
-  S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
-  return;
-}
+// if (FD->isThisDeclarationADefinition()) {
+//   S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
+//   return;
+// }
   } else {
 const auto *VD = cast(D);
 if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
@@ -5628,10 +5628,10 @@
   }
 
   auto *FD = cast(D);
-  if (FD->isThisDeclarationADefinition()) {
-S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
-return;
-  }
+  // if (FD->isThisDeclarationADefinition()) {
+  //   S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+  //   return;
+  // }
 
   StringRef Str;
   SourceLocation ArgLoc;
@@ -5650,10 +5650,10 @@
   }
 
   auto *FD = cast(D);
-  if (FD->isThisDeclarationADefinition()) {
-S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
-return;
-  }
+  // if (FD->isThisDeclarationADefinition()) {
+  //   S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+  //   return;
+  // }
 
   StringRef Str;
   SourceLocation ArgLoc;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68028: [clang] Add no_builtin attribute

2019-10-03 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked 3 inline comments as done.
gchatelet added inline comments.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1098-1099
+
+  if (D->hasAttr())
+D->dropAttr();
+

gchatelet wrote:
> aaron.ballman wrote:
> > Just making sure I understand the semantics you want: redeclarations do not 
> > have to have matching lists of builtins, but instead the definition will 
> > use a merged list? e.g.,
> > ```
> > [[clang::no_builtin("memset")]] void whatever();
> > [[clang::no_builtin("memcpy")]] void whatever();
> > 
> > [[clang::no_builtin("memmove")]] void whatever() {
> >  // Will not use memset, memcpy, or memmove builtins.
> > }
> > ```
> > That seems a bit strange, to me. In fact, being able to apply this 
> > attribute to a declaration seems a bit like a mistake -- this only impacts 
> > the definition of the function, and I can't imagine good things coming from 
> > hypothetical code like:
> > ```
> > [[clang::no_builtin("memset")]] void whatever();
> > #include "whatever.h" // Provides a library declaration of whatever() with 
> > no restrictions on it
> > ```
> > WDYT about restricting this attribute to only appear on definitions?
> That's a very good point. Thx for noticing.
> Indeed I think it only makes sense to have the attribute on the function 
> definition.
> 
> I've tried to to use `FunctionDecl->hasBody()` during attribute handling in 
> the Sema phase but it seems like the `FunctionDecl` is not complete at this 
> point.
> All calls to `hasBody()` return `false`, if I repeat the operation in 
> `CGCall` then `hasBody` returns `true` and I can see the `CompoundStatement`.
> 
> Do you have any recommendations on where to perform the check?
So after some investigations it turns out that 
`FunctionDecl::isThisDeclarationADefinition` is buggy (returns always `false`) 
when called from `ProcessDeclAttribute`.
I believe it's because the `CompoundStatement` is not parsed at this point.

As a matter of fact all code using this function in `ProcessDeclAttribute` is 
dead code (see D68379 which disables the dead code, tests are still passing)


I'm unsure of how to fix this, it may be possible of using 
`FunctionDecl::setWillHaveBody`in [[ 
https://github.com/llvm/llvm-project/blob/0577a0cedbc5be4cd4c20ba53d3dbdac6bff9a0a/clang/lib/Sema/SemaDecl.cpp#L8820
 | this switch ]].


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68268: [Alignment][NFC] Remove StoreInst::setAlignment(unsigned)

2019-10-03 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 222991.
gchatelet marked 6 inline comments as done.
gchatelet added a comment.

- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68268/new/

https://reviews.llvm.org/D68268

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/IR/Instructions.h
  llvm/lib/CodeGen/AtomicExpandPass.cpp
  llvm/lib/IR/Core.cpp
  llvm/lib/IR/Instructions.cpp
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/lib/Transforms/Scalar/LICM.cpp
  llvm/lib/Transforms/Scalar/SROA.cpp
  llvm/lib/Transforms/Utils/SimplifyCFG.cpp
  llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
  polly/lib/CodeGen/BlockGenerators.cpp

Index: polly/lib/CodeGen/BlockGenerators.cpp
===
--- polly/lib/CodeGen/BlockGenerators.cpp
+++ polly/lib/CodeGen/BlockGenerators.cpp
@@ -1209,7 +1209,7 @@
 StoreInst *Store = Builder.CreateStore(Vector, VectorPtr);
 
 if (!Aligned)
-  Store->setAlignment(8);
+  Store->setAlignment(Align(8));
   } else {
 for (unsigned i = 0; i < ScalarMaps.size(); i++) {
   Value *Scalar = Builder.CreateExtractElement(Vector, Builder.getInt32(i));
Index: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
===
--- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -4024,7 +4024,7 @@
   if (!Alignment)
 Alignment = DL->getABITypeAlignment(SI->getValueOperand()->getType());
 
-  ST->setAlignment(Alignment);
+  ST->setAlignment(Align(Alignment));
   Value *V = propagateMetadata(ST, E->Scalars);
   if (NeedToShuffleReuses) {
 V = Builder.CreateShuffleVector(V, UndefValue::get(VecTy),
Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp
===
--- llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -3087,15 +3087,15 @@
   // store that doesn't execute.
   if (MinAlignment != 0) {
 // Choose the minimum of all non-zero alignments.
-SI->setAlignment(MinAlignment);
+SI->setAlignment(Align(MinAlignment));
   } else if (MaxAlignment != 0) {
 // Choose the minimal alignment between the non-zero alignment and the ABI
 // default alignment for the type of the stored value.
-SI->setAlignment(std::min(MaxAlignment, TypeAlignment));
+SI->setAlignment(Align(std::min(MaxAlignment, TypeAlignment)));
   } else {
 // If both alignments are zero, use ABI default alignment for the type of
 // the stored value.
-SI->setAlignment(TypeAlignment);
+SI->setAlignment(Align(TypeAlignment));
   }
 
   QStore->eraseFromParent();
Index: llvm/lib/Transforms/Scalar/SROA.cpp
===
--- llvm/lib/Transforms/Scalar/SROA.cpp
+++ llvm/lib/Transforms/Scalar/SROA.cpp
@@ -3127,7 +3127,7 @@
   Value *Op = SI->getOperand(0);
   StoreAlign = DL.getABITypeAlignment(Op->getType());
 }
-SI->setAlignment(std::min(StoreAlign, getSliceAlign()));
+SI->setAlignment(MaybeAlign(std::min(StoreAlign, getSliceAlign(;
 continue;
   }
 
Index: llvm/lib/Transforms/Scalar/LICM.cpp
===
--- llvm/lib/Transforms/Scalar/LICM.cpp
+++ llvm/lib/Transforms/Scalar/LICM.cpp
@@ -1790,7 +1790,7 @@
   StoreInst *NewSI = new StoreInst(LiveInValue, Ptr, InsertPos);
   if (UnorderedAtomic)
 NewSI->setOrdering(AtomicOrdering::Unordered);
-  NewSI->setAlignment(Alignment);
+  NewSI->setAlignment(MaybeAlign(Alignment));
   NewSI->setDebugLoc(DL);
   if (AATags)
 NewSI->setAAMetadata(AATags);
Index: llvm/lib/Transforms/Scalar/GVNHoist.cpp
===
--- llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -894,8 +894,8 @@
   ++NumLoadsRemoved;
 } else if (auto *ReplacementStore = dyn_cast(Repl)) {
   ReplacementStore->setAlignment(
-  std::min(ReplacementStore->getAlignment(),
-   cast(I)->getAlignment()));
+  MaybeAlign(std::min(ReplacementStore->getAlignment(),
+  cast(I)->getAlignment(;
   ++NumStoresRemoved;
 } else if (auto *ReplacementAlloca = dyn_cast(Repl)) {
   ReplacementAlloca->setAlignment(
Index: llvm/lib/Transforms/Scalar/AlignmentFr

[PATCH] D68268: [Alignment][NFC] Remove StoreInst::setAlignment(unsigned)

2019-10-03 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added inline comments.



Comment at: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:4027
 
-  ST->setAlignment(Alignment);
+  ST->setAlignment(Align(Alignment));
   Value *V = propagateMetadata(ST, E->Scalars);

courbet wrote:
> I don't think there are any guarantees that `getABITypeAlignment` is non-zero 
> for now.
Actually it is guaranteed to be an `Align`.
You can have a look at the current implementation: 
https://github.com/llvm/llvm-project/blob/18f805a7ea5f369ef523821693f1176b40bcfc7e/llvm/lib/IR/DataLayout.cpp#L752


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68268/new/

https://reviews.llvm.org/D68268



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68274: [Alignment][Clang][NFC] Add CharUnits::getAsAlign

2019-10-03 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked 5 inline comments as done.
gchatelet added inline comments.



Comment at: clang/lib/CodeGen/CGObjCMac.cpp:6323
 GV->setSection("__DATA, __objc_data");
-  GV->setAlignment(
-  CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
+  GV->setAlignment(llvm::Align(
+  CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy)));

courbet wrote:
> I don;t think `getABITypeAlignment` makes  any promisses on the return value.
It is, I posted a comment on the other patch 
https://reviews.llvm.org/D68268#inline-614898


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68274/new/

https://reviews.llvm.org/D68274



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68274: [Alignment][Clang][NFC] Add CharUnits::getAsAlign

2019-10-03 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 222994.
gchatelet marked an inline comment as done.
gchatelet added a comment.

- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68274/new/

https://reviews.llvm.org/D68274

Files:
  clang/include/clang/AST/CharUnits.h
  clang/lib/CodeGen/CGCUDANV.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/CodeGen/CGExprCXX.cpp
  clang/lib/CodeGen/CGExprConstant.cpp
  clang/lib/CodeGen/CGObjCGNU.cpp
  clang/lib/CodeGen/CGObjCMac.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/ConstantInitBuilder.cpp
  clang/lib/CodeGen/CoverageMappingGen.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp

Index: clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
===
--- clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -279,7 +279,7 @@
 *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, Data,
 "__clang_ast");
 // The on-disk hashtable needs to be aligned.
-ASTSym->setAlignment(8);
+ASTSym->setAlignment(llvm::Align(8));
 
 // Mach-O also needs a segment name.
 if (Triple.isOSBinFormatMachO())
Index: clang/lib/CodeGen/MicrosoftCXXABI.cpp
===
--- clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -2355,7 +2355,7 @@
   /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage,
   /*Initializer=*/nullptr, VarName,
   /*InsertBefore=*/nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
-  GV->setAlignment(Align.getQuantity());
+  GV->setAlignment(Align.getAsAlign());
   return ConstantAddress(GV, Align);
 }
 
@@ -2498,7 +2498,7 @@
  GV->getLinkage(), Zero, GuardName.str());
 GuardVar->setVisibility(GV->getVisibility());
 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
-GuardVar->setAlignment(GuardAlign.getQuantity());
+GuardVar->setAlignment(GuardAlign.getAsAlign());
 if (GuardVar->isWeakForLinker())
   GuardVar->setComdat(
   CGM.getModule().getOrInsertComdat(GuardVar->getName()));
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2194,7 +2194,7 @@
 guard->setVisibility(var->getVisibility());
 // If the variable is thread-local, so is its guard variable.
 guard->setThreadLocalMode(var->getThreadLocalMode());
-guard->setAlignment(guardAlignment.getQuantity());
+guard->setAlignment(guardAlignment.getAsAlign());
 
 // The ABI says: "It is suggested that it be emitted in the same COMDAT
 // group as the associated data object." In practice, this doesn't work for
@@ -2547,7 +2547,7 @@
 Guard->setThreadLocal(true);
 
 CharUnits GuardAlign = CharUnits::One();
-Guard->setAlignment(GuardAlign.getQuantity());
+Guard->setAlignment(GuardAlign.getAsAlign());
 
 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(
 InitFunc, OrderedInits, ConstantAddress(Guard, GuardAlign));
@@ -3479,7 +3479,7 @@
 
   CharUnits Align =
   CGM.getContext().toCharUnitsFromBits(CGM.getTarget().getPointerAlign(0));
-  GV->setAlignment(Align.getQuantity());
+  GV->setAlignment(Align.getAsAlign());
 
   // The Itanium ABI specifies that type_info objects must be globally
   // unique, with one exception: if the type is an incomplete class
Index: clang/lib/CodeGen/CoverageMappingGen.cpp
===
--- clang/lib/CodeGen/CoverageMappingGen.cpp
+++ clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -1442,7 +1442,7 @@
   CovDataVal, llvm::getCoverageMappingVarName());
 
   CovData->setSection(getCoverageSection(CGM));
-  CovData->setAlignment(8);
+  CovData->setAlignment(llvm::Align(8));
 
   // Make sure the data doesn't get deleted.
   CGM.addUsedGlobal(CovData);
Index: clang/lib/CodeGen/ConstantInitBuilder.cpp
===
--- clang/lib/CodeGen/ConstantInitBuilder.cpp
+++ clang/lib/CodeGen/ConstantInitBuilder.cpp
@@ -79,7 +79,7 @@
  /*insert before*/ nullptr,
  llvm::GlobalValue::NotThreadLocal,
  addressSpace);
-  GV->setAlignment(alignment.getQuantity());
+  GV->setAlignment(alignment.getAsAlign());
   resolveSelfReferences(GV);
   return GV;
 }
Index:

[PATCH] D68274: [Alignment][Clang][NFC] Add CharUnits::getAsAlign

2019-10-03 Thread Guillaume Chatelet via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL373592: [Alignment][Clang][NFC] Add CharUnits::getAsAlign 
(authored by gchatelet, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D68274?vs=222994&id=222996#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68274/new/

https://reviews.llvm.org/D68274

Files:
  cfe/trunk/include/clang/AST/CharUnits.h
  cfe/trunk/lib/CodeGen/CGCUDANV.cpp
  cfe/trunk/lib/CodeGen/CGCall.cpp
  cfe/trunk/lib/CodeGen/CGCleanup.cpp
  cfe/trunk/lib/CodeGen/CGDecl.cpp
  cfe/trunk/lib/CodeGen/CGExpr.cpp
  cfe/trunk/lib/CodeGen/CGExprAgg.cpp
  cfe/trunk/lib/CodeGen/CGExprCXX.cpp
  cfe/trunk/lib/CodeGen/CGExprConstant.cpp
  cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
  cfe/trunk/lib/CodeGen/CGObjCMac.cpp
  cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
  cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
  cfe/trunk/lib/CodeGen/CodeGenFunction.h
  cfe/trunk/lib/CodeGen/CodeGenModule.cpp
  cfe/trunk/lib/CodeGen/ConstantInitBuilder.cpp
  cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
  cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
  cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
  cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp

Index: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
===
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -2355,7 +2355,7 @@
   /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage,
   /*Initializer=*/nullptr, VarName,
   /*InsertBefore=*/nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
-  GV->setAlignment(Align.getQuantity());
+  GV->setAlignment(Align.getAsAlign());
   return ConstantAddress(GV, Align);
 }
 
@@ -2498,7 +2498,7 @@
  GV->getLinkage(), Zero, GuardName.str());
 GuardVar->setVisibility(GV->getVisibility());
 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
-GuardVar->setAlignment(GuardAlign.getQuantity());
+GuardVar->setAlignment(GuardAlign.getAsAlign());
 if (GuardVar->isWeakForLinker())
   GuardVar->setComdat(
   CGM.getModule().getOrInsertComdat(GuardVar->getName()));
Index: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
===
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp
@@ -907,7 +907,7 @@
  llvm::GlobalVariable::NotThreadLocal,
 CGM.getContext().getTargetAddressSpace(addressSpace));
   emitter.finalize(GV);
-  GV->setAlignment(Align.getQuantity());
+  GV->setAlignment(Align.getAsAlign());
   CGM.setAddrOfConstantCompoundLiteral(E, GV);
   return ConstantAddress(GV, Align);
 }
Index: cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
===
--- cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
+++ cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
@@ -1442,7 +1442,7 @@
   CovDataVal, llvm::getCoverageMappingVarName());
 
   CovData->setSection(getCoverageSection(CGM));
-  CovData->setAlignment(8);
+  CovData->setAlignment(llvm::Align(8));
 
   // Make sure the data doesn't get deleted.
   CGM.addUsedGlobal(CovData);
Index: cfe/trunk/lib/CodeGen/CGCall.cpp
===
--- cfe/trunk/lib/CodeGen/CGCall.cpp
+++ cfe/trunk/lib/CodeGen/CGCall.cpp
@@ -3841,7 +3841,7 @@
   AI = CreateTempAlloca(ArgStruct, "argmem");
 }
 auto Align = CallInfo.getArgStructAlignment();
-AI->setAlignment(llvm::MaybeAlign(Align.getQuantity()));
+AI->setAlignment(Align.getAsAlign());
 AI->setUsedWithInAlloca(true);
 assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
 ArgMemory = Address(AI, Align);
Index: cfe/trunk/lib/CodeGen/ConstantInitBuilder.cpp
===
--- cfe/trunk/lib/CodeGen/ConstantInitBuilder.cpp
+++ cfe/trunk/lib/CodeGen/ConstantInitBuilder.cpp
@@ -79,7 +79,7 @@
  /*insert before*/ nullptr,
  llvm::GlobalValue::NotThreadLocal,
  addressSpace);
-  GV->setAlignment(alignment.getQuantity());
+  GV->setAlignment(alignment.getAsAlign());
   resolveSelfReferences(GV);
   return GV;
 }
Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h
===
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h
@@ -1034,7 +1034,7 @@
 assert(isInConditionalBranch());
 llvm::BasicBlock *block = OutermostConditional->getStartingBlock();
 auto store = new llvm::StoreInst(value, addr.getPointer(), &block->back());
-store->setAlignment(addr.getAlignment().getQuantity());
+store->s

[PATCH] D68268: [Alignment][NFC] Remove StoreInst::setAlignment(unsigned)

2019-10-03 Thread Guillaume Chatelet via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL373595: [Alignment][NFC] Remove 
StoreInst::setAlignment(unsigned) (authored by gchatelet, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D68268?vs=222991&id=223000#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68268/new/

https://reviews.llvm.org/D68268

Files:
  cfe/trunk/lib/CodeGen/CGBuiltin.cpp
  llvm/trunk/include/llvm/IR/IRBuilder.h
  llvm/trunk/include/llvm/IR/Instructions.h
  llvm/trunk/lib/CodeGen/AtomicExpandPass.cpp
  llvm/trunk/lib/IR/Core.cpp
  llvm/trunk/lib/IR/Instructions.cpp
  llvm/trunk/lib/Transforms/IPO/Attributor.cpp
  llvm/trunk/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
  llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/trunk/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/trunk/lib/Transforms/Scalar/LICM.cpp
  llvm/trunk/lib/Transforms/Scalar/SROA.cpp
  llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
  llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp
  polly/trunk/lib/CodeGen/BlockGenerators.cpp

Index: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
===
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp
@@ -11193,7 +11193,7 @@
 // Unaligned nontemporal store of the scalar value.
 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC);
 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
-SI->setAlignment(1);
+SI->setAlignment(llvm::Align::None());
 return SI;
   }
   // Rotate is a special case of funnel shift - 1st 2 args are the same.
Index: llvm/trunk/lib/Transforms/IPO/Attributor.cpp
===
--- llvm/trunk/lib/Transforms/IPO/Attributor.cpp
+++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp
@@ -2467,7 +2467,7 @@
   if (SI->getAlignment() < getAssumedAlign()) {
 STATS_DECLTRACK(AAAlign, Store,
 "Number of times alignemnt added to a store");
-SI->setAlignment(getAssumedAlign());
+SI->setAlignment(Align(getAssumedAlign()));
 Changed = ChangeStatus::CHANGED;
   }
   } else if (auto *LI = dyn_cast(U.getUser())) {
Index: llvm/trunk/lib/Transforms/Scalar/SROA.cpp
===
--- llvm/trunk/lib/Transforms/Scalar/SROA.cpp
+++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp
@@ -3127,7 +3127,7 @@
   Value *Op = SI->getOperand(0);
   StoreAlign = DL.getABITypeAlignment(Op->getType());
 }
-SI->setAlignment(std::min(StoreAlign, getSliceAlign()));
+SI->setAlignment(MaybeAlign(std::min(StoreAlign, getSliceAlign(;
 continue;
   }
 
Index: llvm/trunk/lib/Transforms/Scalar/GVNHoist.cpp
===
--- llvm/trunk/lib/Transforms/Scalar/GVNHoist.cpp
+++ llvm/trunk/lib/Transforms/Scalar/GVNHoist.cpp
@@ -894,8 +894,8 @@
   ++NumLoadsRemoved;
 } else if (auto *ReplacementStore = dyn_cast(Repl)) {
   ReplacementStore->setAlignment(
-  std::min(ReplacementStore->getAlignment(),
-   cast(I)->getAlignment()));
+  MaybeAlign(std::min(ReplacementStore->getAlignment(),
+  cast(I)->getAlignment(;
   ++NumStoresRemoved;
 } else if (auto *ReplacementAlloca = dyn_cast(Repl)) {
   ReplacementAlloca->setAlignment(
Index: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
===
--- llvm/trunk/lib/Transforms/Scalar/LICM.cpp
+++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp
@@ -1790,7 +1790,7 @@
   StoreInst *NewSI = new StoreInst(LiveInValue, Ptr, InsertPos);
   if (UnorderedAtomic)
 NewSI->setOrdering(AtomicOrdering::Unordered);
-  NewSI->setAlignment(Alignment);
+  NewSI->setAlignment(MaybeAlign(Alignment));
   NewSI->setDebugLoc(DL);
   if (AATags)
 NewSI->setAAMetadata(AATags);
Index: llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
===
--- llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
+++ llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
@@ -329,7 +329,7 @@
 SI->getPointerOperand(), SE);
 
   if (NewAlignment > SI->getAlignment()) {
-SI->setAlignment(NewAlignment);
+SI->setAlignment(MaybeAlign(NewAlignment));
 ++NumStoreAlignChanged;
   }
 } else if (MemIntrinsic *MI = dyn_cast(J)) {
Index: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
===
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp

[PATCH] D68028: [clang] Add no_builtin attribute

2019-10-08 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked 2 inline comments as done.
gchatelet added inline comments.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1098-1099
+
+  if (D->hasAttr())
+D->dropAttr();
+

aaron.ballman wrote:
> gchatelet wrote:
> > gchatelet wrote:
> > > aaron.ballman wrote:
> > > > Just making sure I understand the semantics you want: redeclarations do 
> > > > not have to have matching lists of builtins, but instead the definition 
> > > > will use a merged list? e.g.,
> > > > ```
> > > > [[clang::no_builtin("memset")]] void whatever();
> > > > [[clang::no_builtin("memcpy")]] void whatever();
> > > > 
> > > > [[clang::no_builtin("memmove")]] void whatever() {
> > > >  // Will not use memset, memcpy, or memmove builtins.
> > > > }
> > > > ```
> > > > That seems a bit strange, to me. In fact, being able to apply this 
> > > > attribute to a declaration seems a bit like a mistake -- this only 
> > > > impacts the definition of the function, and I can't imagine good things 
> > > > coming from hypothetical code like:
> > > > ```
> > > > [[clang::no_builtin("memset")]] void whatever();
> > > > #include "whatever.h" // Provides a library declaration of whatever() 
> > > > with no restrictions on it
> > > > ```
> > > > WDYT about restricting this attribute to only appear on definitions?
> > > That's a very good point. Thx for noticing.
> > > Indeed I think it only makes sense to have the attribute on the function 
> > > definition.
> > > 
> > > I've tried to to use `FunctionDecl->hasBody()` during attribute handling 
> > > in the Sema phase but it seems like the `FunctionDecl` is not complete at 
> > > this point.
> > > All calls to `hasBody()` return `false`, if I repeat the operation in 
> > > `CGCall` then `hasBody` returns `true` and I can see the 
> > > `CompoundStatement`.
> > > 
> > > Do you have any recommendations on where to perform the check?
> > So after some investigations it turns out that 
> > `FunctionDecl::isThisDeclarationADefinition` is buggy (returns always 
> > `false`) when called from `ProcessDeclAttribute`.
> > I believe it's because the `CompoundStatement` is not parsed at this point.
> > 
> > As a matter of fact all code using this function in `ProcessDeclAttribute` 
> > is dead code (see D68379 which disables the dead code, tests are still 
> > passing)
> > 
> > 
> > I'm unsure of how to fix this, it may be possible of using 
> > `FunctionDecl::setWillHaveBody`in [[ 
> > https://github.com/llvm/llvm-project/blob/0577a0cedbc5be4cd4c20ba53d3dbdac6bff9a0a/clang/lib/Sema/SemaDecl.cpp#L8820
> >  | this switch ]].
> > So after some investigations it turns out that 
> > FunctionDecl::isThisDeclarationADefinition is buggy (returns always false) 
> > when called from ProcessDeclAttribute.
> 
> That is a bit odd to me; we call it in a half dozen places in 
> SemaDeclAttr.cpp, all of which get called from `ProcessDeclAttribute`. Are 
> ALL of those uses broken currently?!
> 
> > As a matter of fact all code using this function in ProcessDeclAttribute is 
> > dead code (see D68379 which disables the dead code, tests are still passing)
> 
> You got four of the six. What about the use in 
> `handleObjCSuppresProtocolAttr()` and the second use in `handleAliasAttr()`?
> 
> > I'm unsure of how to fix this, it may be possible of using 
> > FunctionDecl::setWillHaveBodyin this switch.
> 
> I'm also unsure of a good way forward. @rsmith may have ideas too.
> That is a bit odd to me; we call it in a half dozen places in 
> SemaDeclAttr.cpp, all of which get called from ProcessDeclAttribute. Are ALL 
> of those uses broken currently?!
> You got four of the six. What about the use in 
> handleObjCSuppresProtocolAttr() and the second use in handleAliasAttr()?

It really is `FunctionDecl::isThisDeclarationADefinition` that is buggy, the 
other places where we call `isThisDeclarationADefinition` in `SemaDeclAttr.cpp` 
are ok, i.e. `VarDecl::isThisDeclarationADefinition` and 
`ObjCProtocolDecl::isThisDeclarationADefinition`

I tried to use `FunctionDecl::setWillHaveBody`but it broke many tests so it 
seems inappropriate.



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68701: Adds a isDefinitionKind to FunctionDecl

2019-10-09 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Tentatively fixing the bug described in 
https://reviews.llvm.org/D68028#inline-614831.
This is not a good solution though since `isThisDeclarationADefinition` still 
doesn't work as expected.

Having `isThisDeclarationADefinition` use `isDefinitionKind` is breaking a lot 
of tests.
I believe there is broken code out there relying on the current behavior.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68701

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/DeclBase.h
  clang/lib/AST/Decl.cpp
  clang/lib/Sema/SemaDecl.cpp

Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -8565,6 +8565,26 @@
   isVirtualOkay);
   if (!NewFD) return nullptr;
 
+  // If a function is defined as defaulted or deleted, mark it as such now.
+  // FIXME: Does this ever happen? ActOnStartOfFunctionDef forces the function
+  // definition kind to FDK_Definition.
+  switch (D.getFunctionDefinitionKind()) {
+case FDK_Declaration:
+  break;
+
+case FDK_Definition:
+  NewFD->setDefinitionKind();
+  break;
+
+case FDK_Defaulted:
+  NewFD->setDefaulted();
+  break;
+
+case FDK_Deleted:
+  NewFD->setDeletedAsWritten();
+  break;
+  }
+
   if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer())
 NewFD->setTopLevelDeclInObjCContainer();
 
@@ -8817,23 +8837,6 @@
   NewFD->setAccess(AS_public);
 }
 
-// If a function is defined as defaulted or deleted, mark it as such now.
-// FIXME: Does this ever happen? ActOnStartOfFunctionDef forces the function
-// definition kind to FDK_Definition.
-switch (D.getFunctionDefinitionKind()) {
-  case FDK_Declaration:
-  case FDK_Definition:
-break;
-
-  case FDK_Defaulted:
-NewFD->setDefaulted();
-break;
-
-  case FDK_Deleted:
-NewFD->setDeletedAsWritten();
-break;
-}
-
 if (isa(NewFD) && DC == CurContext &&
 D.isFunctionDefinition()) {
   // C++ [class.mfct]p2:
Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -2792,6 +2792,7 @@
   FunctionDeclBits.IsMultiVersion = false;
   FunctionDeclBits.IsCopyDeductionCandidate = false;
   FunctionDeclBits.HasODRHash = false;
+  FunctionDeclBits.IsDefinitionKind = false;
 }
 
 void FunctionDecl::getNameForDiagnostic(
Index: clang/include/clang/AST/DeclBase.h
===
--- clang/include/clang/AST/DeclBase.h
+++ clang/include/clang/AST/DeclBase.h
@@ -1534,10 +1534,14 @@
 
 /// Store the ODRHash after first calculation.
 uint64_t HasODRHash : 1;
+
+/// Indicates that this function has the FDK_Definition
+/// FunctionDefinitionKind.
+uint64_t IsDefinitionKind : 1;
   };
 
   /// Number of non-inherited bits in FunctionDeclBitfields.
-  enum { NumFunctionDeclBits = 25 };
+  enum { NumFunctionDeclBits = 26 };
 
   /// Stores the bits used by CXXConstructorDecl. If modified
   /// NumCXXConstructorDeclBits and the accessor
@@ -1549,12 +1553,12 @@
 /// For the bits in FunctionDeclBitfields.
 uint64_t : NumFunctionDeclBits;
 
-/// 24 bits to fit in the remaining available space.
+/// 25 bits to fit in the remaining available space.
 /// Note that this makes CXXConstructorDeclBitfields take
 /// exactly 64 bits and thus the width of NumCtorInitializers
 /// will need to be shrunk if some bit is added to NumDeclContextBitfields,
 /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields.
-uint64_t NumCtorInitializers : 23;
+uint64_t NumCtorInitializers : 22;
 uint64_t IsInheritingConstructor : 1;
 
 /// Whether this constructor has a trail-allocated explicit specifier.
Index: clang/include/clang/AST/Decl.h
===
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -2284,6 +2284,12 @@
   bool willHaveBody() const { return FunctionDeclBits.WillHaveBody; }
   void setWillHaveBody(bool V = true) { FunctionDeclBits.WillHaveBody = V; }
 
+  /// True if this function is of type of Kind FDK_Definition.
+  bool isDefinitionKind() const { return FunctionDeclBits.IsDefinitionKind; }
+  void setDefinitionKind(bool V = true) {
+FunctionDeclBits.IsDefinitionKind = V;
+  }
+
   /// True if this function is considered a multiversioned function.
   bool isMultiVersion() const {
 return getCanonicalDecl()->FunctionDeclBits.IsMultiVersion;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68028: [clang] Add no_builtin attribute

2019-10-09 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet marked an inline comment as done.
gchatelet added inline comments.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:1098-1099
+
+  if (D->hasAttr())
+D->dropAttr();
+

gchatelet wrote:
> aaron.ballman wrote:
> > gchatelet wrote:
> > > gchatelet wrote:
> > > > aaron.ballman wrote:
> > > > > Just making sure I understand the semantics you want: redeclarations 
> > > > > do not have to have matching lists of builtins, but instead the 
> > > > > definition will use a merged list? e.g.,
> > > > > ```
> > > > > [[clang::no_builtin("memset")]] void whatever();
> > > > > [[clang::no_builtin("memcpy")]] void whatever();
> > > > > 
> > > > > [[clang::no_builtin("memmove")]] void whatever() {
> > > > >  // Will not use memset, memcpy, or memmove builtins.
> > > > > }
> > > > > ```
> > > > > That seems a bit strange, to me. In fact, being able to apply this 
> > > > > attribute to a declaration seems a bit like a mistake -- this only 
> > > > > impacts the definition of the function, and I can't imagine good 
> > > > > things coming from hypothetical code like:
> > > > > ```
> > > > > [[clang::no_builtin("memset")]] void whatever();
> > > > > #include "whatever.h" // Provides a library declaration of whatever() 
> > > > > with no restrictions on it
> > > > > ```
> > > > > WDYT about restricting this attribute to only appear on definitions?
> > > > That's a very good point. Thx for noticing.
> > > > Indeed I think it only makes sense to have the attribute on the 
> > > > function definition.
> > > > 
> > > > I've tried to to use `FunctionDecl->hasBody()` during attribute 
> > > > handling in the Sema phase but it seems like the `FunctionDecl` is not 
> > > > complete at this point.
> > > > All calls to `hasBody()` return `false`, if I repeat the operation in 
> > > > `CGCall` then `hasBody` returns `true` and I can see the 
> > > > `CompoundStatement`.
> > > > 
> > > > Do you have any recommendations on where to perform the check?
> > > So after some investigations it turns out that 
> > > `FunctionDecl::isThisDeclarationADefinition` is buggy (returns always 
> > > `false`) when called from `ProcessDeclAttribute`.
> > > I believe it's because the `CompoundStatement` is not parsed at this 
> > > point.
> > > 
> > > As a matter of fact all code using this function in 
> > > `ProcessDeclAttribute` is dead code (see D68379 which disables the dead 
> > > code, tests are still passing)
> > > 
> > > 
> > > I'm unsure of how to fix this, it may be possible of using 
> > > `FunctionDecl::setWillHaveBody`in [[ 
> > > https://github.com/llvm/llvm-project/blob/0577a0cedbc5be4cd4c20ba53d3dbdac6bff9a0a/clang/lib/Sema/SemaDecl.cpp#L8820
> > >  | this switch ]].
> > > So after some investigations it turns out that 
> > > FunctionDecl::isThisDeclarationADefinition is buggy (returns always 
> > > false) when called from ProcessDeclAttribute.
> > 
> > That is a bit odd to me; we call it in a half dozen places in 
> > SemaDeclAttr.cpp, all of which get called from `ProcessDeclAttribute`. Are 
> > ALL of those uses broken currently?!
> > 
> > > As a matter of fact all code using this function in ProcessDeclAttribute 
> > > is dead code (see D68379 which disables the dead code, tests are still 
> > > passing)
> > 
> > You got four of the six. What about the use in 
> > `handleObjCSuppresProtocolAttr()` and the second use in `handleAliasAttr()`?
> > 
> > > I'm unsure of how to fix this, it may be possible of using 
> > > FunctionDecl::setWillHaveBodyin this switch.
> > 
> > I'm also unsure of a good way forward. @rsmith may have ideas too.
> > That is a bit odd to me; we call it in a half dozen places in 
> > SemaDeclAttr.cpp, all of which get called from ProcessDeclAttribute. Are 
> > ALL of those uses broken currently?!
> > You got four of the six. What about the use in 
> > handleObjCSuppresProtocolAttr() and the second use in handleAliasAttr()?
> 
> It really is `FunctionDecl::isThisDeclarationADefinition` that is buggy, the 
> other places where we call `isThisDeclarationADefinition` in 
> `SemaDeclAttr.cpp` are ok, i.e. `VarDecl::isThisDeclarationADefinition` and 
> `ObjCProtocolDecl::isThisDeclarationADefinition`
> 
> I tried to use `FunctionDecl::setWillHaveBody`but it broke many tests so it 
> seems inappropriate.
> 
I've tried to fix it in D68701. I'm pretty sure this is not the right way to do 
it though,
@rsmith any idea on how to proceed?

In the meantime I'll add a FIXME and move on with this patch if you don't mind.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68028: [clang] Add no_builtin attribute

2019-10-09 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 224082.
gchatelet added a comment.

- Address aaron ballman comments
- Checks function name validity and errors when passed 0 argument.
- Update documentation and rebase
- Rewrote mergeNoBuiltinAttr
- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/no-builtin.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/no-builtin.c

Index: clang/test/Sema/no-builtin.c
===
--- /dev/null
+++ clang/test/Sema/no-builtin.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsyntax-only -verify %s
+
+void valid_attribute_wildcard() __attribute__((no_builtin("*"))) {}
+void valid_attribute_function() __attribute__((no_builtin("memcpy"))) {}
+void valid_attribute_functions() __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memcmp"))) {}
+
+void no_builtin_no_argument() __attribute__((no_builtin)) {}
+// expected-error@-1 {{'no_builtin' attribute takes at least 1 argument}}
+
+void no_builtin_no_argument2() __attribute__((no_builtin())) {}
+// expected-error@-1 {{'no_builtin' attribute takes at least 1 argument}}
+
+void invalid_builtin() __attribute__((no_builtin("not_a_builtin"))) {}
+// expected-error@-1 {{'not_a_builtin' is not a valid function name for no_builtin}}
+
+void wildcard_and_functionname() __attribute__((no_builtin("*", "memcpy"))) {}
+// expected-error@-1 {{no_builtin wildcard (*) cannot be composed with other function names}}
+
+void wildcard_and_functionname2() __attribute__((no_builtin("*"))) __attribute__((no_builtin("memcpy"))) {}
+// expected-error@-1 {{no_builtin wildcard (*) cannot be composed with other function names}}
+
+void nobuiltin_on_declaration() __attribute__((no_builtin("memcpy")));
+// expected-error@-1 {{no_builtin attribute is permitted on definitions only}}
+
+int __attribute__((no_builtin("*"))) variable;
+// expected-warning@-1 {{'no_builtin' attribute only applies to functions}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -74,6 +74,7 @@
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
+// CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
 // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
 // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable)
Index: clang/test/CodeGen/no-builtin.c
===
--- /dev/null
+++ clang/test/CodeGen/no-builtin.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @foo_no_mempcy() #0
+void foo_no_mempcy() __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_builtins() #1
+void foo_no_builtins() __attribute__((no_builtin("*"))) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_memset() #2
+void foo_no_mempcy_memset() __attribute__((no_builtin("memset", "memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs() #2
+void separate_attrs() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @wildcard_wins() #1
+void wildcard_wins() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("*"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
+// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
+// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1068,6 +1068,56 @@
   S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast(D)));
 }
 
+NoBuiltinAttr *
+Sema::mergeNoBuiltinAttr(Decl *D, const AttributeCommonInfo &CI,
+ llvm::ArrayRef FunctionNames) {
+  llvm::SmallVector Names;
+  bool HasWildcard = false;
+
+  const auto TestAndPushBack = [&Names, &HasWildcard](StringRef Name) {
+HasWildcard |= (Name == "*");
+Names.push_back(Name)

[PATCH] D68028: [clang] Add no_builtin attribute

2019-10-09 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 224085.
gchatelet added a comment.

- Remove leftovers


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/no-builtin.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/no-builtin.c

Index: clang/test/Sema/no-builtin.c
===
--- /dev/null
+++ clang/test/Sema/no-builtin.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsyntax-only -verify %s
+
+void valid_attribute_wildcard() __attribute__((no_builtin("*"))) {}
+void valid_attribute_function() __attribute__((no_builtin("memcpy"))) {}
+void valid_attribute_functions() __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memcmp"))) {}
+
+void no_builtin_no_argument() __attribute__((no_builtin)) {}
+// expected-error@-1 {{'no_builtin' attribute takes at least 1 argument}}
+
+void no_builtin_no_argument2() __attribute__((no_builtin())) {}
+// expected-error@-1 {{'no_builtin' attribute takes at least 1 argument}}
+
+void invalid_builtin() __attribute__((no_builtin("not_a_builtin"))) {}
+// expected-error@-1 {{'not_a_builtin' is not a valid function name for no_builtin}}
+
+void wildcard_and_functionname() __attribute__((no_builtin("*", "memcpy"))) {}
+// expected-error@-1 {{no_builtin wildcard (*) cannot be composed with other function names}}
+
+void wildcard_and_functionname2() __attribute__((no_builtin("*"))) __attribute__((no_builtin("memcpy"))) {}
+// expected-error@-1 {{no_builtin wildcard (*) cannot be composed with other function names}}
+
+void nobuiltin_on_declaration() __attribute__((no_builtin("memcpy")));
+// expected-error@-1 {{no_builtin attribute is permitted on definitions only}}
+
+int __attribute__((no_builtin("*"))) variable;
+// expected-warning@-1 {{'no_builtin' attribute only applies to functions}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -74,6 +74,7 @@
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
+// CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
 // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
 // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable)
Index: clang/test/CodeGen/no-builtin.c
===
--- /dev/null
+++ clang/test/CodeGen/no-builtin.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @foo_no_mempcy() #0
+void foo_no_mempcy() __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_builtins() #1
+void foo_no_builtins() __attribute__((no_builtin("*"))) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_memset() #2
+void foo_no_mempcy_memset() __attribute__((no_builtin("memset", "memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs() #2
+void separate_attrs() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
+// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
+// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1068,6 +1068,56 @@
   S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast(D)));
 }
 
+NoBuiltinAttr *
+Sema::mergeNoBuiltinAttr(Decl *D, const AttributeCommonInfo &CI,
+ llvm::ArrayRef FunctionNames) {
+  llvm::SmallVector Names;
+  bool HasWildcard = false;
+
+  const auto TestAndPushBack = [&Names, &HasWildcard](StringRef Name) {
+HasWildcard |= (Name == "*");
+Names.push_back(Name);
+  };
+
+  if (const auto *NBA = D->getAttr())
+for (StringRef FunctionName : NBA->functionNames())
+  TestAndPushBack(FunctionName);
+
+  for (StringRef FunctionName : FunctionNames)
+TestAndPushBack(FunctionName);
+
+  if (HasWildcard && Names.size() > 1)
+Diag(D->getLocation(),
+ diag::err_attribute_no_builtin_wildcar

[PATCH] D68028: [clang] Add no_builtin attribute

2019-10-10 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 224271.
gchatelet added a comment.

- rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/no-builtin.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/no-builtin.c

Index: clang/test/Sema/no-builtin.c
===
--- /dev/null
+++ clang/test/Sema/no-builtin.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsyntax-only -verify %s
+
+void valid_attribute_wildcard() __attribute__((no_builtin("*"))) {}
+void valid_attribute_function() __attribute__((no_builtin("memcpy"))) {}
+void valid_attribute_functions() __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memcmp"))) {}
+
+void no_builtin_no_argument() __attribute__((no_builtin)) {}
+// expected-error@-1 {{'no_builtin' attribute takes at least 1 argument}}
+
+void no_builtin_no_argument2() __attribute__((no_builtin())) {}
+// expected-error@-1 {{'no_builtin' attribute takes at least 1 argument}}
+
+void invalid_builtin() __attribute__((no_builtin("not_a_builtin"))) {}
+// expected-error@-1 {{'not_a_builtin' is not a valid function name for no_builtin}}
+
+void wildcard_and_functionname() __attribute__((no_builtin("*", "memcpy"))) {}
+// expected-error@-1 {{no_builtin wildcard (*) cannot be composed with other function names}}
+
+void wildcard_and_functionname2() __attribute__((no_builtin("*"))) __attribute__((no_builtin("memcpy"))) {}
+// expected-error@-1 {{no_builtin wildcard (*) cannot be composed with other function names}}
+
+void nobuiltin_on_declaration() __attribute__((no_builtin("memcpy")));
+// expected-error@-1 {{no_builtin attribute is permitted on definitions only}}
+
+int __attribute__((no_builtin("*"))) variable;
+// expected-warning@-1 {{'no_builtin' attribute only applies to functions}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -74,6 +74,7 @@
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
+// CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
 // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
 // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable)
Index: clang/test/CodeGen/no-builtin.c
===
--- /dev/null
+++ clang/test/CodeGen/no-builtin.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @foo_no_mempcy() #0
+void foo_no_mempcy() __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_twice() #0
+void foo_no_mempcy_twice() __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_builtins() #1
+void foo_no_builtins() __attribute__((no_builtin("*"))) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_memset() #2
+void foo_no_mempcy_memset() __attribute__((no_builtin("memset", "memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs() #2
+void separate_attrs() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs_ordering() #2
+void separate_attrs_ordering() __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memset"))) {}
+
+// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
+// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
+// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1068,6 +1068,60 @@
   S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast(D)));
 }
 
+NoBuiltinAttr *
+Sema::mergeNoBuiltinAttr(Decl *D, const AttributeCommonInfo &CI,
+ llvm::ArrayRef FunctionNames) {
+  llvm::SmallVector Names;
+  bool HasWildcard = false;
+
+  const auto TestAndPushBack = [&Names, &HasWildcard](StringRef Name) {
+HasWildcard |= (Name == "*");
+Names.push_back(Name);
+  };
+
+  if (const

[PATCH] D68028: [clang] Add no_builtin attribute

2019-10-10 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet added a comment.

It should be ready to submit, @aaron.ballman @courbet can you take a final look?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68028: [clang] Add no_builtin attribute

2019-10-10 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet updated this revision to Diff 224285.
gchatelet marked 2 inline comments as done.
gchatelet added a comment.

- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68028/new/

https://reviews.llvm.org/D68028

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/no-builtin.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/no-builtin.c

Index: clang/test/Sema/no-builtin.c
===
--- /dev/null
+++ clang/test/Sema/no-builtin.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsyntax-only -verify %s
+
+void valid_attribute_wildcard() __attribute__((no_builtin("*"))) {}
+void valid_attribute_function() __attribute__((no_builtin("memcpy"))) {}
+void valid_attribute_functions() __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memcmp"))) {}
+
+void no_builtin_no_argument() __attribute__((no_builtin)) {}
+// expected-error@-1 {{'no_builtin' attribute takes at least 1 argument}}
+
+void no_builtin_no_argument2() __attribute__((no_builtin())) {}
+// expected-error@-1 {{'no_builtin' attribute takes at least 1 argument}}
+
+void invalid_builtin() __attribute__((no_builtin("not_a_builtin"))) {}
+// expected-error@-1 {{'not_a_builtin' is not a valid builtin name for no_builtin}}
+
+void wildcard_and_functionname() __attribute__((no_builtin("*", "memcpy"))) {}
+// expected-error@-1 {{no_builtin wildcard (*) cannot be composed with other builtin names}}
+
+void wildcard_and_functionname2() __attribute__((no_builtin("*"))) __attribute__((no_builtin("memcpy"))) {}
+// expected-error@-1 {{no_builtin wildcard (*) cannot be composed with other builtin names}}
+
+void nobuiltin_on_declaration() __attribute__((no_builtin("memcpy")));
+// expected-error@-1 {{no_builtin attribute is permitted on definitions only}}
+
+int __attribute__((no_builtin("*"))) variable;
+// expected-warning@-1 {{'no_builtin' attribute only applies to functions}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -74,6 +74,7 @@
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
+// CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
 // CHECK-NEXT: NoDebug (SubjectMatchRule_type_alias, SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
 // CHECK-NEXT: NoDestroy (SubjectMatchRule_variable)
Index: clang/test/CodeGen/no-builtin.c
===
--- /dev/null
+++ clang/test/CodeGen/no-builtin.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @foo_no_mempcy() #0
+void foo_no_mempcy() __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_twice() #0
+void foo_no_mempcy_twice() __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @foo_no_builtins() #1
+void foo_no_builtins() __attribute__((no_builtin("*"))) {}
+
+// CHECK-LABEL: define void @foo_no_mempcy_memset() #2
+void foo_no_mempcy_memset() __attribute__((no_builtin("memset", "memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs() #2
+void separate_attrs() __attribute__((no_builtin("memset"))) __attribute__((no_builtin("memcpy"))) {}
+
+// CHECK-LABEL: define void @separate_attrs_ordering() #2
+void separate_attrs_ordering() __attribute__((no_builtin("memcpy"))) __attribute__((no_builtin("memset"))) {}
+
+// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
+// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
+// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1068,6 +1068,60 @@
   S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast(D)));
 }
 
+NoBuiltinAttr *
+Sema::mergeNoBuiltinAttr(Decl *D, const AttributeCommonInfo &CI,
+ llvm::ArrayRef BuiltinNames) {
+  llvm::SmallVector Names;
+  bool HasWildcard = false;
+
+  const auto TestAndPushBack = [&Names, &HasWildcard](StringRef Name) {
+HasWildcard |= (Name == "*")

  1   2   3   >