gchatelet created this revision.
gchatelet added reviewers: efriedma, courbet.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
gchatelet added a subscriber: abrachet.
gchatelet added a comment.

Buggy trace here 
<https://reviews.llvm.org/rG04a309dd0be3aea17ab6e84f8bfc046c1f044be2#910776>


If the size parameter of `__builtin_memcpy_inline` comes from an 
un-instantiated template parameter current code would crash.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76504

Files:
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/builtins-memcpy-inline.c
  clang/test/Sema/builtins-memcpy-inline.cpp


Index: clang/test/Sema/builtins-memcpy-inline.cpp
===================================================================
--- clang/test/Sema/builtins-memcpy-inline.cpp
+++ clang/test/Sema/builtins-memcpy-inline.cpp
@@ -30,3 +30,9 @@
 void test_memcpy_inline_non_constant_size(void *dst, const void *src, unsigned 
size) {
   __builtin_memcpy_inline(dst, src, size); // expected-error {{argument to 
'__builtin_memcpy_inline' must be a constant integer}}
 }
+
+template <unsigned size>
+void test_memcpy_inline_template(void *dst, const void *src) {
+  // we do not try to evaluate size in non intantiated templates.
+  __builtin_memcpy_inline(dst, src, size);
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1649,11 +1649,18 @@
   case Builtin::BI__builtin_nontemporal_store:
     return SemaBuiltinNontemporalOverloaded(TheCallResult);
   case Builtin::BI__builtin_memcpy_inline: {
+    clang::Expr *DstOp = TheCall->getArg(0);
+    clang::Expr *SrcOp = TheCall->getArg(1);
+    clang::Expr *SizeOp = TheCall->getArg(2);
+    // If any arg is instantiation dependent we bail out.
+    if (DstOp->isInstantiationDependent() ||
+        SrcOp->isInstantiationDependent() || 
SizeOp->isInstantiationDependent())
+      break;
     // __builtin_memcpy_inline size argument is a constant by definition.
-    if (TheCall->getArg(2)->EvaluateKnownConstInt(Context).isNullValue())
+    if (SizeOp->EvaluateKnownConstInt(Context).isNullValue())
       break;
-    CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
-    CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc());
+    CheckNonNullArgument(*this, DstOp, TheCall->getExprLoc());
+    CheckNonNullArgument(*this, SrcOp, TheCall->getExprLoc());
     break;
   }
 #define BUILTIN(ID, TYPE, ATTRS)


Index: clang/test/Sema/builtins-memcpy-inline.cpp
===================================================================
--- clang/test/Sema/builtins-memcpy-inline.cpp
+++ clang/test/Sema/builtins-memcpy-inline.cpp
@@ -30,3 +30,9 @@
 void test_memcpy_inline_non_constant_size(void *dst, const void *src, unsigned size) {
   __builtin_memcpy_inline(dst, src, size); // expected-error {{argument to '__builtin_memcpy_inline' must be a constant integer}}
 }
+
+template <unsigned size>
+void test_memcpy_inline_template(void *dst, const void *src) {
+  // we do not try to evaluate size in non intantiated templates.
+  __builtin_memcpy_inline(dst, src, size);
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1649,11 +1649,18 @@
   case Builtin::BI__builtin_nontemporal_store:
     return SemaBuiltinNontemporalOverloaded(TheCallResult);
   case Builtin::BI__builtin_memcpy_inline: {
+    clang::Expr *DstOp = TheCall->getArg(0);
+    clang::Expr *SrcOp = TheCall->getArg(1);
+    clang::Expr *SizeOp = TheCall->getArg(2);
+    // If any arg is instantiation dependent we bail out.
+    if (DstOp->isInstantiationDependent() ||
+        SrcOp->isInstantiationDependent() || SizeOp->isInstantiationDependent())
+      break;
     // __builtin_memcpy_inline size argument is a constant by definition.
-    if (TheCall->getArg(2)->EvaluateKnownConstInt(Context).isNullValue())
+    if (SizeOp->EvaluateKnownConstInt(Context).isNullValue())
       break;
-    CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc());
-    CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc());
+    CheckNonNullArgument(*this, DstOp, TheCall->getExprLoc());
+    CheckNonNullArgument(*this, SrcOp, TheCall->getExprLoc());
     break;
   }
 #define BUILTIN(ID, TYPE, ATTRS)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to