Improve type validation for root() functions.
Change-Id: I16af906106d4b38966e37534703f959f7d6c956c
diff --git a/slang_rs_root.cpp b/slang_rs_root.cpp
index 6391739..2309a8d 100644
--- a/slang_rs_root.cpp
+++ b/slang_rs_root.cpp
@@ -50,7 +50,8 @@
const clang::ASTContext &C = FD->getASTContext();
if (isRootRSFunc(FD)) {
- if (FD->getNumParams() == 0) {
+ unsigned int numParams = FD->getNumParams();
+ if (numParams == 0) {
// Graphics root function, so verify that it returns an int
if (FD->getResultType().getCanonicalType() != C.IntTy) {
Diags->Report(
@@ -72,10 +73,71 @@
}
// Validate remaining parameter types
- // TODO(srhines)
+ const clang::ParmVarDecl *tooManyParams = NULL;
+ for (unsigned int i = 0; i < numParams; i++) {
+ const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
+ clang::QualType QT = PVD->getType().getCanonicalType();
+ switch (i) {
+ case 0: // const T1 *ain
+ case 2: { // const T3 *usrData
+ if (!QT->isPointerType() ||
+ !QT->getPointeeType().isConstQualified()) {
+ Diags->Report(
+ clang::FullSourceLoc(PVD->getLocation(),
+ Diags->getSourceManager()),
+ Diags->getCustomDiagID(clang::Diagnostic::Error,
+ "compute root() parameter must be a "
+ "const pointer type"));
+ valid = false;
+ }
+ break;
+ }
+ case 1: { // T2 *aout
+ if (!QT->isPointerType()) {
+ Diags->Report(
+ clang::FullSourceLoc(PVD->getLocation(),
+ Diags->getSourceManager()),
+ Diags->getCustomDiagID(clang::Diagnostic::Error,
+ "compute root() parameter must be a "
+ "pointer type"));
+ valid = false;
+ }
+ break;
+ }
+ case 3: // unsigned int x
+ case 4: // unsigned int y
+ case 5: // unsigned int z
+ case 6: { // unsigned int ar
+ if (QT.getUnqualifiedType() != C.UnsignedIntTy) {
+ Diags->Report(
+ clang::FullSourceLoc(PVD->getLocation(),
+ Diags->getSourceManager()),
+ Diags->getCustomDiagID(clang::Diagnostic::Error,
+ "compute root() parameter must be a "
+ "uint32_t type"));
+ valid = false;
+ }
+ break;
+ }
+ default: {
+ if (!tooManyParams) {
+ tooManyParams = PVD;
+ }
+ break;
+ }
+ }
+ }
+ if (tooManyParams) {
+ Diags->Report(
+ clang::FullSourceLoc(tooManyParams->getLocation(),
+ Diags->getSourceManager()),
+ Diags->getCustomDiagID(clang::Diagnostic::Error,
+ "too many compute root() parameters "
+ "specified"));
+ valid = false;
+ }
}
- }
- else if (isInitRSFunc(FD)) {
+ } else if (isInitRSFunc(FD)) {
if (FD->getNumParams() != 0) {
Diags->Report(
clang::FullSourceLoc(FD->getLocation(), Diags->getSourceManager()),
@@ -93,8 +155,7 @@
"return type"));
valid = false;
}
- }
- else {
+ } else {
slangAssert(false && "must be called on init or root function!");
}
diff --git a/slang_rs_root.h b/slang_rs_root.h
index 235181b..1c7efa5 100644
--- a/slang_rs_root.h
+++ b/slang_rs_root.h
@@ -24,8 +24,6 @@
#include "slang_assert.h"
#include "slang_rs_context.h"
-//#include "slang_rs_export_type.h"
-//#include "slang_rs_exportable.h"
namespace clang {
class FunctionDecl;
@@ -36,8 +34,6 @@
// Base class for handling root() functions (including reflection of
// control-side code for issuing rsForEach).
class RSRoot {
- //friend class RSContext;
-
private:
std::string mName;
std::string mMangledName;
@@ -90,10 +86,8 @@
static bool validateSpecialFuncDecl(clang::Diagnostic *Diags,
const clang::FunctionDecl *FD);
-
}; // RSRoot
-
} // namespace slang
#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_ROOT_H_ NOLINT
diff --git a/tests/F_root_compute/root_compute.rs b/tests/F_root_compute/root_compute.rs
deleted file mode 100644
index f07de57..0000000
--- a/tests/F_root_compute/root_compute.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(foo)
-
-int root(int ain, int aout, void *usrData) {
- return 10;
-}
diff --git a/tests/F_root_compute/stderr.txt.expect b/tests/F_root_compute/stderr.txt.expect
deleted file mode 100644
index 681d14b..0000000
--- a/tests/F_root_compute/stderr.txt.expect
+++ /dev/null
@@ -1 +0,0 @@
-root_compute.rs:4:5: error: compute root() is required to return a void type
diff --git a/tests/F_root_compute_non_const_ain/root_compute_non_const_ain.rs b/tests/F_root_compute_non_const_ain/root_compute_non_const_ain.rs
new file mode 100644
index 0000000..5cbf52b
--- /dev/null
+++ b/tests/F_root_compute_non_const_ain/root_compute_non_const_ain.rs
@@ -0,0 +1,5 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(int *ain) {
+}
diff --git a/tests/F_root_compute_non_const_ain/stderr.txt.expect b/tests/F_root_compute_non_const_ain/stderr.txt.expect
new file mode 100644
index 0000000..539e033
--- /dev/null
+++ b/tests/F_root_compute_non_const_ain/stderr.txt.expect
@@ -0,0 +1 @@
+root_compute_non_const_ain.rs:4:16: error: compute root() parameter must be a const pointer type
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_non_const_ain/stdout.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/F_root_compute_non_const_ain/stdout.txt.expect
diff --git a/tests/F_root_compute_non_const_non_ptr_ain/root_compute_non_const_non_ptr_ain.rs b/tests/F_root_compute_non_const_non_ptr_ain/root_compute_non_const_non_ptr_ain.rs
new file mode 100644
index 0000000..364b7c8
--- /dev/null
+++ b/tests/F_root_compute_non_const_non_ptr_ain/root_compute_non_const_non_ptr_ain.rs
@@ -0,0 +1,5 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(int ain) {
+}
diff --git a/tests/F_root_compute_non_const_non_ptr_ain/stderr.txt.expect b/tests/F_root_compute_non_const_non_ptr_ain/stderr.txt.expect
new file mode 100644
index 0000000..f774ed2
--- /dev/null
+++ b/tests/F_root_compute_non_const_non_ptr_ain/stderr.txt.expect
@@ -0,0 +1 @@
+root_compute_non_const_non_ptr_ain.rs:4:15: error: compute root() parameter must be a const pointer type
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_non_const_non_ptr_ain/stdout.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/F_root_compute_non_const_non_ptr_ain/stdout.txt.expect
diff --git a/tests/F_root_compute_non_const_usrData/root_compute_non_const_usrData.rs b/tests/F_root_compute_non_const_usrData/root_compute_non_const_usrData.rs
new file mode 100644
index 0000000..46dc642
--- /dev/null
+++ b/tests/F_root_compute_non_const_usrData/root_compute_non_const_usrData.rs
@@ -0,0 +1,5 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int *aout, void *usrData) {
+}
diff --git a/tests/F_root_compute_non_const_usrData/stderr.txt.expect b/tests/F_root_compute_non_const_usrData/stderr.txt.expect
new file mode 100644
index 0000000..053353d
--- /dev/null
+++ b/tests/F_root_compute_non_const_usrData/stderr.txt.expect
@@ -0,0 +1 @@
+root_compute_non_const_usrData.rs:4:44: error: compute root() parameter must be a const pointer type
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_non_const_usrData/stdout.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/F_root_compute_non_const_usrData/stdout.txt.expect
diff --git a/tests/F_root_compute_non_ptr_ain/root_compute_non_ptr_ain.rs b/tests/F_root_compute_non_ptr_ain/root_compute_non_ptr_ain.rs
new file mode 100644
index 0000000..a311d47
--- /dev/null
+++ b/tests/F_root_compute_non_ptr_ain/root_compute_non_ptr_ain.rs
@@ -0,0 +1,5 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int ain) {
+}
diff --git a/tests/F_root_compute_non_ptr_ain/stderr.txt.expect b/tests/F_root_compute_non_ptr_ain/stderr.txt.expect
new file mode 100644
index 0000000..3ffb17a
--- /dev/null
+++ b/tests/F_root_compute_non_ptr_ain/stderr.txt.expect
@@ -0,0 +1 @@
+root_compute_non_ptr_ain.rs:4:21: error: compute root() parameter must be a const pointer type
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_non_ptr_ain/stdout.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/F_root_compute_non_ptr_ain/stdout.txt.expect
diff --git a/tests/F_root_compute_non_ptr_aout/root_compute_non_ptr_aout.rs b/tests/F_root_compute_non_ptr_aout/root_compute_non_ptr_aout.rs
new file mode 100644
index 0000000..351e335
--- /dev/null
+++ b/tests/F_root_compute_non_ptr_aout/root_compute_non_ptr_aout.rs
@@ -0,0 +1,5 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int aout) {
+}
diff --git a/tests/F_root_compute_non_ptr_aout/stderr.txt.expect b/tests/F_root_compute_non_ptr_aout/stderr.txt.expect
new file mode 100644
index 0000000..0d256c0
--- /dev/null
+++ b/tests/F_root_compute_non_ptr_aout/stderr.txt.expect
@@ -0,0 +1 @@
+root_compute_non_ptr_aout.rs:4:31: error: compute root() parameter must be a pointer type
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_non_ptr_aout/stdout.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/F_root_compute_non_ptr_aout/stdout.txt.expect
diff --git a/tests/F_root_compute_non_ptr_usrData/root_compute_non_ptr_usrData.rs b/tests/F_root_compute_non_ptr_usrData/root_compute_non_ptr_usrData.rs
new file mode 100644
index 0000000..ce67f8a
--- /dev/null
+++ b/tests/F_root_compute_non_ptr_usrData/root_compute_non_ptr_usrData.rs
@@ -0,0 +1,5 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int *aout, const int usrData) {
+}
diff --git a/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect b/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect
new file mode 100644
index 0000000..44940b8
--- /dev/null
+++ b/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect
@@ -0,0 +1 @@
+root_compute_non_ptr_usrData.rs:4:48: error: compute root() parameter must be a const pointer type
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_non_ptr_usrData/stdout.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/F_root_compute_non_ptr_usrData/stdout.txt.expect
diff --git a/tests/F_root_compute_non_uint32_t_xyzar/root_compute_non_uint32_t_xyzar.rs b/tests/F_root_compute_non_uint32_t_xyzar/root_compute_non_uint32_t_xyzar.rs
new file mode 100644
index 0000000..94360b8
--- /dev/null
+++ b/tests/F_root_compute_non_uint32_t_xyzar/root_compute_non_uint32_t_xyzar.rs
@@ -0,0 +1,6 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int *aout, const void *usrData,
+ int x, float y, double z, uchar ar) {
+}
diff --git a/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect b/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect
new file mode 100644
index 0000000..beaadfc
--- /dev/null
+++ b/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect
@@ -0,0 +1,4 @@
+root_compute_non_uint32_t_xyzar.rs:5:15: error: compute root() parameter must be a uint32_t type
+root_compute_non_uint32_t_xyzar.rs:5:24: error: compute root() parameter must be a uint32_t type
+root_compute_non_uint32_t_xyzar.rs:5:34: error: compute root() parameter must be a uint32_t type
+root_compute_non_uint32_t_xyzar.rs:5:43: error: compute root() parameter must be a uint32_t type
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_non_uint32_t_xyzar/stdout.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/F_root_compute_non_uint32_t_xyzar/stdout.txt.expect
diff --git a/tests/F_root_compute_non_void_ret/root_compute_non_void_ret.rs b/tests/F_root_compute_non_void_ret/root_compute_non_void_ret.rs
new file mode 100644
index 0000000..fe0c3cc
--- /dev/null
+++ b/tests/F_root_compute_non_void_ret/root_compute_non_void_ret.rs
@@ -0,0 +1,6 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int root(const int *ain, int *aout, const void *usrData) {
+ return 10;
+}
diff --git a/tests/F_root_compute_non_void_ret/stderr.txt.expect b/tests/F_root_compute_non_void_ret/stderr.txt.expect
new file mode 100644
index 0000000..f7eaec7
--- /dev/null
+++ b/tests/F_root_compute_non_void_ret/stderr.txt.expect
@@ -0,0 +1 @@
+root_compute_non_void_ret.rs:4:5: error: compute root() is required to return a void type
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_non_void_ret/stdout.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/F_root_compute_non_void_ret/stdout.txt.expect
diff --git a/tests/F_root_compute_really_bad/root_compute_really_bad.rs b/tests/F_root_compute_really_bad/root_compute_really_bad.rs
new file mode 100644
index 0000000..469575a
--- /dev/null
+++ b/tests/F_root_compute_really_bad/root_compute_really_bad.rs
@@ -0,0 +1,7 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int root(int ain, int aout, int usrData, float x, double y, uchar z, ushort ar,
+ uint32_t extra1, uint32_t extra2) {
+ return 10;
+}
diff --git a/tests/F_root_compute_really_bad/stderr.txt.expect b/tests/F_root_compute_really_bad/stderr.txt.expect
new file mode 100644
index 0000000..7babf29
--- /dev/null
+++ b/tests/F_root_compute_really_bad/stderr.txt.expect
@@ -0,0 +1,9 @@
+root_compute_really_bad.rs:4:5: error: compute root() is required to return a void type
+root_compute_really_bad.rs:4:14: error: compute root() parameter must be a const pointer type
+root_compute_really_bad.rs:4:23: error: compute root() parameter must be a pointer type
+root_compute_really_bad.rs:4:33: error: compute root() parameter must be a const pointer type
+root_compute_really_bad.rs:4:48: error: compute root() parameter must be a uint32_t type
+root_compute_really_bad.rs:4:58: error: compute root() parameter must be a uint32_t type
+root_compute_really_bad.rs:4:67: error: compute root() parameter must be a uint32_t type
+root_compute_really_bad.rs:4:77: error: compute root() parameter must be a uint32_t type
+root_compute_really_bad.rs:5:19: error: too many compute root() parameters specified
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_really_bad/stdout.txt.expect
similarity index 100%
rename from tests/F_root_compute/stdout.txt.expect
rename to tests/F_root_compute_really_bad/stdout.txt.expect
diff --git a/tests/F_root_compute_too_many_args/root_compute_too_many_args.rs b/tests/F_root_compute_too_many_args/root_compute_too_many_args.rs
new file mode 100644
index 0000000..655fba3
--- /dev/null
+++ b/tests/F_root_compute_too_many_args/root_compute_too_many_args.rs
@@ -0,0 +1,7 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int *aout, const void *usrData,
+ uint32_t x, uint32_t y, uint32_t z, uint32_t ar,
+ uint32_t extra1, uint32_t extra2) {
+}
diff --git a/tests/F_root_compute_too_many_args/stderr.txt.expect b/tests/F_root_compute_too_many_args/stderr.txt.expect
new file mode 100644
index 0000000..78b3266
--- /dev/null
+++ b/tests/F_root_compute_too_many_args/stderr.txt.expect
@@ -0,0 +1 @@
+root_compute_too_many_args.rs:6:20: error: too many compute root() parameters specified
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/F_root_compute_too_many_args/stdout.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/F_root_compute_too_many_args/stdout.txt.expect
diff --git a/tests/P_root_compute/root_compute.rs b/tests/P_root_compute/root_compute.rs
new file mode 100644
index 0000000..a7c6ffd
--- /dev/null
+++ b/tests/P_root_compute/root_compute.rs
@@ -0,0 +1,6 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int *aout, const void *usrData,
+ uint32_t x, uint32_t y, uint32_t z, uint32_t ar) {
+}
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/P_root_compute/stderr.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/P_root_compute/stderr.txt.expect
diff --git a/tests/P_root_compute/stdout.txt.expect b/tests/P_root_compute/stdout.txt.expect
new file mode 100644
index 0000000..acc7d56
--- /dev/null
+++ b/tests/P_root_compute/stdout.txt.expect
@@ -0,0 +1 @@
+Generating ScriptC_root_compute.java ...
diff --git a/tests/P_root_compute_non_void_ptr_usrData/root_compute_non_void_ptr_usrData.rs b/tests/P_root_compute_non_void_ptr_usrData/root_compute_non_void_ptr_usrData.rs
new file mode 100644
index 0000000..cf7f318
--- /dev/null
+++ b/tests/P_root_compute_non_void_ptr_usrData/root_compute_non_void_ptr_usrData.rs
@@ -0,0 +1,5 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int *aout, const int *usrData) {
+}
diff --git a/tests/F_root_compute/stdout.txt.expect b/tests/P_root_compute_non_void_ptr_usrData/stderr.txt.expect
similarity index 100%
copy from tests/F_root_compute/stdout.txt.expect
copy to tests/P_root_compute_non_void_ptr_usrData/stderr.txt.expect
diff --git a/tests/P_root_compute_non_void_ptr_usrData/stdout.txt.expect b/tests/P_root_compute_non_void_ptr_usrData/stdout.txt.expect
new file mode 100644
index 0000000..25a9ab9
--- /dev/null
+++ b/tests/P_root_compute_non_void_ptr_usrData/stdout.txt.expect
@@ -0,0 +1 @@
+Generating ScriptC_root_compute_non_void_ptr_usrData.java ...