Skip to content

Commit 294bd0a

Browse files
author
ripley
committed
Do not try to print non-existent element.
Avoid some issues with invalid C objected to by UBSAN when margin = NULL. git-svn-id: https://svn.r-project.org/R/trunk@87475 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent ebea1a2 commit 294bd0a

File tree

2 files changed

+21
-17
lines changed

2 files changed

+21
-17
lines changed

src/library/stats/R/loglin.R

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,12 @@ loglin <- function(table, margin, start = rep(1, length(table)), fit =
4646

4747
z <- .Call(C_LogLin, dtab, conf, table, start, nmar, eps, iter)
4848

49-
if (print)
50-
cat(z$nlast, "iterations: deviation", z$dev[z$nlast], "\n")
49+
if (print) {
50+
if(z$nlast > 0)
51+
cat(z$nlast, "iterations: deviation", z$dev[z$nlast], "\n")
52+
else
53+
cat(z$nlast, "iterations\n")
54+
}
5155

5256
fit <- z$fit
5357
attributes(fit) <- attributes(table)

src/library/stats/src/loglin.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ loglin(int nvar, int *dim, int ncon, int *config, int ntab,
4343

4444
/* Parameter adjustments */
4545
--dim;
46-
--locmar;
47-
config -= nvar + 1;
46+
// --locmar;
47+
// config -= nvar + 1;
4848
--fit;
4949
--table;
50-
--marg;
50+
// --marg;
5151
--u;
5252
--dev;
5353

@@ -91,22 +91,22 @@ loglin(int nvar, int *dim, int ncon, int *config, int ntab,
9191
if (y == 0.) goto L5;
9292
x /= y;
9393
for (i = 1; i <= size; i++) fit[i] = x * fit[i];
94-
if (ncon <= 0 || config[nvar + 1] == 0) return;
94+
if (ncon <= 0 || config[0] == 0) return;
9595

9696
/* Allocate marginal tables */
9797

9898
point = 1;
9999
for (i = 1; i <= ncon; i++) {
100100
/* A zero beginning a configuration indicates that the list is
101101
completed */
102-
if (config[i * nvar + 1] == 0) goto L160;
102+
if (config[i * nvar + 1 - (nvar+1)] == 0) goto L160;
103103
/* Get marginal table size. While doing this task, see if the
104104
configuration list contains duplications or elements out of
105105
range. */
106106
size = 1;
107107
for (j = 0; j < nvar; j++) check[j] = 0;
108108
for (j = 1; j <= nvar; j++) {
109-
k = config[j + i * nvar];
109+
k = config[j + i * nvar - (nvar+1)];
110110
/* A zero indicates the end of the string. */
111111
if (k == 0) goto L130;
112112
/* See if element is valid. */
@@ -128,11 +128,11 @@ loglin(int nvar, int *dim, int ncon, int *config, int ntab,
128128
if (size > nu) goto L35;
129129

130130
/* LOCMAR points to marginal tables to be placed in MARG */
131-
locmar[i] = point;
131+
locmar[i-1] = point;
132132
point += size;
133133
}
134134

135-
/* Get N, number of valid configurations */
135+
/* Get N, number of valid configations */
136136

137137
i = ncon + 1;
138138
L160:
@@ -146,9 +146,9 @@ loglin(int nvar, int *dim, int ncon, int *config, int ntab,
146146

147147
for (i = 1; i <= n; i++) {
148148
for (j = 1; j <= nvar; j++) {
149-
icon[j - 1] = config[j + i * nvar];
149+
icon[j - 1] = config[j + i * nvar - (nvar+1)];
150150
}
151-
collap(nvar, &table[1], &marg[1], locmar[i], &dim[1], icon);
151+
collap(nvar, &table[1], marg, locmar[i-1], &dim[1], icon);
152152
}
153153

154154
/* Perform iterations */
@@ -158,9 +158,10 @@ loglin(int nvar, int *dim, int ncon, int *config, int ntab,
158158
marginal during a cycle */
159159
xmax = 0.;
160160
for (i = 1; i <= n; i++) {
161-
for (j = 1; j <= nvar; j++) icon[j - 1] = config[j + i * nvar];
161+
for (j = 1; j <= nvar; j++)
162+
icon[j - 1] = config[j + i * nvar - (nvar+1)];
162163
collap(nvar, &fit[1], &u[1], 1, &dim[1], icon);
163-
adjust(nvar, &fit[1], &u[1], &marg[1], &locmar[i], &dim[1], icon, &xmax);
164+
adjust(nvar, &fit[1], &u[1], marg, &locmar[i-1], &dim[1], icon, &xmax);
164165
}
165166
/* Test convergence */
166167
dev[k] = xmax;
@@ -349,9 +350,8 @@ SEXP LogLin(SEXP dtab, SEXP conf, SEXP table, SEXP start,
349350
maxit = asInteger(iter),
350351
nlast, ifault;
351352
double maxdev = asReal(eps);
352-
if (ncon == 0 || nmar == 0)
353-
Rf_error("invalid zero-length input(s): ncon %d, nmar %d",
354-
ncon, nmar);
353+
// if (ncon == 0 || nmar == 0)
354+
// Rf_error("invalid zero-length input(s): ncon %d, nmar %d", ncon, nmar);
355355
SEXP fit = PROTECT(TYPEOF(start) == REALSXP ? duplicate(start) :
356356
coerceVector(start, REALSXP)),
357357
locmar = PROTECT(allocVector(INTSXP, ncon)),

0 commit comments

Comments
 (0)