Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 81e51c9

Browse files
committed
More nullary C++ class constructor checks.
1 parent b640de6 commit 81e51c9

4 files changed

Lines changed: 18 additions & 12 deletions

File tree

Cython/Compiler/Nodes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,6 +2048,8 @@ def analyse_declarations(self, env):
20482048
if self.return_type.is_array and self.visibility != 'extern':
20492049
error(self.pos,
20502050
"Function cannot return an array")
2051+
if self.return_type.is_cpp_class:
2052+
self.return_type.check_nullary_constructor(self.pos, "used as a return value")
20512053

20522054
if self.overridable and not env.is_module_scope:
20532055
if len(self.args) < 1 or not self.args[0].type.is_pyobject:

Cython/Compiler/PyrexTypes.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3205,6 +3205,11 @@ def find_cpp_operation_type(self, operator, operand_type=None):
32053205
func_type = func_type.base_type
32063206
return func_type.return_type
32073207

3208+
def check_nullary_constructor(self, pos, msg="stack allocated"):
3209+
constructor = self.scope.lookup(u'<init>')
3210+
if constructor is not None and best_match([], constructor.all_alternatives()) is None:
3211+
error(pos, "C++ class must have a nullary constructor to be %s" % msg)
3212+
32083213

32093214
class TemplatePlaceholderType(CType):
32103215

Cython/Compiler/Symtab.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,7 @@ def declare_var(self, name, type, pos,
569569
else:
570570
cname = self.mangle(Naming.var_prefix, name)
571571
if type.is_cpp_class and visibility != 'extern':
572-
constructor = type.scope.lookup(u'<init>')
573-
if constructor is not None and PyrexTypes.best_match([], constructor.all_alternatives()) is None:
574-
error(pos, "C++ class must have a no-arg constructor to be stack allocated")
572+
type.check_nullary_constructor(pos)
575573
entry = self.declare(name, cname, type, pos, visibility)
576574
entry.is_variable = 1
577575
if in_pxd and visibility != 'extern':
@@ -1782,10 +1780,7 @@ def declare_var(self, name, type, pos,
17821780
if visibility == 'private':
17831781
cname = c_safe_identifier(cname)
17841782
if type.is_cpp_class and visibility != 'extern':
1785-
constructor = type.scope.lookup(u'<init>')
1786-
if constructor is not None and \
1787-
PyrexTypes.best_match([], constructor.all_alternatives()) is None:
1788-
error(pos, "C++ class must have a no-arg constructor to be a member of an extension type; use a pointer instead")
1783+
type.check_nullary_constructor(pos)
17891784
self.use_utility_code(Code.UtilityCode("#include <new>"))
17901785
entry = self.declare(name, cname, type, pos, visibility)
17911786
entry.is_variable = 1

Cython/Compiler/TypeInference.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ def resolve_dependancy(dep):
390390
types = [assmt.rhs.infer_type(scope)
391391
for assmt in entry.cf_assignments]
392392
if types and Utils.all(types):
393-
entry.type = spanning_type(types, entry.might_overflow)
393+
entry.type = spanning_type(types, entry.might_overflow, entry.pos)
394394
else:
395395
# FIXME: raise a warning?
396396
# print "No assignments", entry.pos, entry
@@ -405,10 +405,10 @@ def resolve_dependancy(dep):
405405
for assmt in entry.cf_assignments
406406
if assmt.type_dependencies(scope) == ()]
407407
if types:
408-
entry.type = spanning_type(types, entry.might_overflow)
408+
entry.type = spanning_type(types, entry.might_overflow, entry.pos)
409409
types = [assmt.infer_type(scope)
410410
for assmt in entry.cf_assignments]
411-
entry.type = spanning_type(types, entry.might_overflow) # might be wider...
411+
entry.type = spanning_type(types, entry.might_overflow, entry.pos) # might be wider...
412412
resolve_dependancy(entry)
413413
del dependancies_by_entry[entry]
414414
if ready_to_infer:
@@ -438,16 +438,20 @@ def find_spanning_type(type1, type2):
438438
return PyrexTypes.c_double_type
439439
return result_type
440440

441-
def aggressive_spanning_type(types, might_overflow):
441+
def aggressive_spanning_type(types, might_overflow, pos):
442442
result_type = reduce(find_spanning_type, types)
443443
if result_type.is_reference:
444444
result_type = result_type.ref_base_type
445+
if result_type.is_cpp_class:
446+
result_type.check_nullary_constructor(pos)
445447
return result_type
446448

447-
def safe_spanning_type(types, might_overflow):
449+
def safe_spanning_type(types, might_overflow, pos):
448450
result_type = reduce(find_spanning_type, types)
449451
if result_type.is_reference:
450452
result_type = result_type.ref_base_type
453+
if result_type.is_cpp_class:
454+
result_type.check_nullary_constructor(pos)
451455
if result_type.is_pyobject:
452456
# In theory, any specific Python type is always safe to
453457
# infer. However, inferring str can cause some existing code

0 commit comments

Comments
 (0)