summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorJoe George <joe@zeroc.com>2023-10-09 13:47:52 -0400
committerGitHub <noreply@github.com>2023-10-09 13:47:52 -0400
commit45cf4a9ccba65d4d2b8129d11c4debcb117cbc68 (patch)
treeadb98c12bd36c24eafc39b00d456cdd03ea051bd /cpp/src
parentRework Java & Java Compat README files (#1538) (diff)
downloadice-45cf4a9ccba65d4d2b8129d11c4debcb117cbc68.tar.bz2
ice-45cf4a9ccba65d4d2b8129d11c4debcb117cbc68.tar.xz
ice-45cf4a9ccba65d4d2b8129d11c4debcb117cbc68.zip
slice2java: fix constructor parameter count check (#1540)
Closes #1539
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Slice/JavaUtil.cpp22
-rw-r--r--cpp/src/Slice/JavaUtil.h9
-rw-r--r--cpp/src/slice2java/Gen.cpp20
-rw-r--r--cpp/src/slice2java/GenCompat.cpp20
4 files changed, 53 insertions, 18 deletions
diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp
index ad20211a1c7..9ad435fbae7 100644
--- a/cpp/src/Slice/JavaUtil.cpp
+++ b/cpp/src/Slice/JavaUtil.cpp
@@ -669,6 +669,28 @@ Slice::computeSerialVersionUUID(const ExceptionPtr& p)
return hashCode;
}
+bool
+Slice::isValidMethodParameterList(const DataMemberList& members, int additionalUnits)
+{
+ // The maximum length of a method parameter list is 255 units, including the implicit 'this' parameter.
+ // Each parameter is 1 unit, except for long and double parameters, which are 2 units.
+ // Start the length at 1 to account for the implicit 'this' parameter (plus any additional units).
+ int length = 1 + additionalUnits;
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*p)->type());
+ if(builtin && (builtin->kind() == Builtin::KindLong || builtin->kind() == Builtin::KindDouble))
+ {
+ length += 2;
+ }
+ else
+ {
+ length++;
+ }
+ }
+ return length <= 255;
+}
+
Slice::JavaOutput::JavaOutput()
{
}
diff --git a/cpp/src/Slice/JavaUtil.h b/cpp/src/Slice/JavaUtil.h
index 326d7adfa1a..d9c6e440d0c 100644
--- a/cpp/src/Slice/JavaUtil.h
+++ b/cpp/src/Slice/JavaUtil.h
@@ -29,6 +29,15 @@ computeSerialVersionUUID(const ExceptionPtr&);
long
computeSerialVersionUUID(const StructPtr&);
+//
+// Returns true if we can generate a method from the given data member list. A Java method
+// can have a maximum of 255 parameters (including the implicit 'this') where each parameter
+// is counted as 1 unit, except for long and double which are counted as 2 units.
+// See https://docs.oracle.com/javase/specs/jvms/se20/html/jvms-4.html#jvms-4.3.3
+//
+bool
+isValidMethodParameterList(const DataMemberList&, int additionalUnits = 0);
+
class JavaOutput : public ::IceUtilInternal::Output
{
public:
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index dbd2ddfd280..7cd4c75f268 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -2552,9 +2552,9 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
out << eb;
//
- // A method cannot have more than 255 parameters (including the implicit "this" argument).
+ // Generate constructor if the parameter list is not too large.
//
- if(allDataMembers.size() < 255)
+ if(isValidMethodParameterList(allDataMembers))
{
DataMemberList baseDataMembers;
if(baseClass)
@@ -2945,9 +2945,9 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
}
//
- // A method cannot have more than 255 parameters (including the implicit "this" argument).
+ // Generate constructor if the parameter list is not too large.
//
- if(allDataMembers.size() < 255)
+ if(isValidMethodParameterList(allDataMembers))
{
if(hasRequiredMembers && hasOptionalMembers)
{
@@ -3010,8 +3010,9 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
//
// Create constructor that takes all data members plus a Throwable.
+ // Do this only when the parameter list is not too large.
//
- if(allDataMembers.size() < 254)
+ if(isValidMethodParameterList(allDataMembers, 1))
{
const string causeParamName = getEscapedParamName(allDataMembers, "cause");
@@ -3090,9 +3091,10 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
out << eb;
//
- // Create constructor that takes all data members plus a Throwable
+ // Create constructor that takes all data members plus a Throwable.
+ // Do this only when the parameter list is not too large.
//
- if(allDataMembers.size() < 254)
+ if(isValidMethodParameterList(allDataMembers, 1))
{
const string causeParamName = getEscapedParamName(allDataMembers, "cause");
@@ -3382,9 +3384,9 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
out << eb;
//
- // A method cannot have more than 255 parameters (including the implicit "this" argument).
+ // Generate constructor if the parameter list is not too large.
//
- if(members.size() < 255)
+ if(isValidMethodParameterList(members))
{
vector<string> paramDecl;
vector<string> paramNames;
diff --git a/cpp/src/slice2java/GenCompat.cpp b/cpp/src/slice2java/GenCompat.cpp
index b3f5504f741..eb76ecbe9cf 100644
--- a/cpp/src/slice2java/GenCompat.cpp
+++ b/cpp/src/slice2java/GenCompat.cpp
@@ -2945,9 +2945,9 @@ Slice::GenCompat::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
out << eb;
//
- // A method cannot have more than 255 parameters (including the implicit "this" argument).
+ // Generate constructor if the parameter list is not too large.
//
- if(allDataMembers.size() < 255)
+ if(isValidMethodParameterList(members))
{
DataMemberList baseDataMembers;
if(baseClass)
@@ -3255,9 +3255,9 @@ Slice::GenCompat::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
}
//
- // A method cannot have more than 255 parameters (including the implicit "this" argument).
+ // Generate constructor if the parameter list is not too large.
//
- if(allDataMembers.size() < 255)
+ if(isValidMethodParameterList(members))
{
if(hasRequiredMembers && hasOptionalMembers)
{
@@ -3319,8 +3319,9 @@ Slice::GenCompat::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
//
// Create constructor that takes all data members plus a Throwable.
+ // Do this only when the parameter list is not too large.
//
- if(allDataMembers.size() < 254)
+ if(isValidMethodParameterList(allDataMembers, 1))
{
const string causeParamName = getEscapedParamName(allDataMembers, "cause");
paramDecl.push_back("Throwable " + causeParamName);
@@ -3397,9 +3398,10 @@ Slice::GenCompat::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
out << eb;
//
- // Create constructor that takes all data members plus a Throwable
+ // Create constructor that takes all data members plus a Throwable.
+ // Do this only when the parameter list is not too large.
//
- if(allDataMembers.size() < 254)
+ if(isValidMethodParameterList(allDataMembers, 1))
{
const string causeParamName = getEscapedParamName(allDataMembers, "cause");
paramDecl.push_back("Throwable " + causeParamName);
@@ -3670,9 +3672,9 @@ Slice::GenCompat::TypesVisitor::visitStructEnd(const StructPtr& p)
out << eb;
//
- // A method cannot have more than 255 parameters (including the implicit "this" argument).
+ // Generate constructor if the parameter list is not too large.
//
- if(members.size() < 255)
+ if(isValidMethodParameterList(members))
{
vector<string> paramDecl;
vector<string> paramNames;