summary refs log tree commit diff stats
path: root/compiler/semexprs.nim
diff options
context:
space:
mode:
authorkonsumlamm <44230978+konsumlamm@users.noreply.github.com>2022-07-28 15:09:58 +0200
committerGitHub <noreply@github.com>2022-07-28 15:09:58 +0200
commit528b6d1c3f001944a7a7754c8884178e365e6871 (patch)
tree7c508959e63fa4d6b2bb77b12a42425eacd8b17b /compiler/semexprs.nim
parent424e87fd0917704155d2e7a94f69435eb50d6037 (diff)
downloadNim-528b6d1c3f001944a7a7754c8884178e365e6871.tar.gz
Warn when casting to a larger type (#20103)
* Warn when casting to a larger type

* Revert change to error message to fix CI
Diffstat (limited to 'compiler/semexprs.nim')
-rw-r--r--compiler/semexprs.nim18
1 files changed, 10 insertions, 8 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 1bb4f49ce..d3c62629d 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -196,10 +196,10 @@ proc checkConvertible(c: PContext, targetTyp: PType, src: PNode): TConvStatus =
     else:
       discard
 
-proc isCastable(c: PContext; dst, src: PType): bool =
+proc isCastable(c: PContext; dst, src: PType, info: TLineInfo): bool =
   ## Checks whether the source type can be cast to the destination type.
   ## Casting is very unrestrictive; casts are allowed as long as
-  ## castDest.size >= src.size, and typeAllowed(dst, skParam)
+  ## dst.size >= src.size, and typeAllowed(dst, skParam)
   #const
   #  castableTypeKinds = {tyInt, tyPtr, tyRef, tyCstring, tyString,
   #                       tySequence, tyPointer, tyNil, tyOpenArray,
@@ -228,19 +228,21 @@ proc isCastable(c: PContext; dst, src: PType): bool =
     # Just assume the programmer knows what he is doing.
     return true
   if dstSize < 0:
-    result = false
+    return false
   elif srcSize < 0:
-    result = false
+    return false
   elif typeAllowed(dst, skParam, c) != nil:
-    result = false
+    return false
   elif dst.kind == tyProc and dst.callConv == ccClosure:
-    result = src.kind == tyProc and src.callConv == ccClosure
+    return src.kind == tyProc and src.callConv == ccClosure
   else:
     result = (dstSize >= srcSize) or
         (skipTypes(dst, abstractInst).kind in IntegralTypes) or
         (skipTypes(src, abstractInst-{tyTypeDesc}).kind in IntegralTypes)
+    if result and (dstSize > srcSize):
+      message(conf, info, warnCastSizes, "target type is larger than source type")
   if result and src.kind == tyNil:
-    result = dst.size <= conf.target.ptrSize
+    return dst.size <= conf.target.ptrSize
 
 proc isSymChoice(n: PNode): bool {.inline.} =
   result = n.kind in nkSymChoices
@@ -359,7 +361,7 @@ proc semCast(c: PContext, n: PNode): PNode =
   let castedExpr = semExprWithType(c, n[1])
   if tfHasMeta in targetType.flags:
     localError(c.config, n[0].info, "cannot cast to a non concrete type: '$1'" % $targetType)
-  if not isCastable(c, targetType, castedExpr.typ):
+  if not isCastable(c, targetType, castedExpr.typ, n.info):
     let tar = $targetType
     let alt = typeToString(targetType, preferDesc)
     let msg = if tar != alt: tar & "=" & alt else: tar